This web page suggests its possible to deploy webapps in parallel, using this function:
HandlerList handlerList = createHandlerList(...);
handlerList.setParallelStart(true);
I can't find anything similar in Jetty 9.4.x and Google seems to return little either.
How can I do this with the latest Jetty?
Parallel startup of Handler Collections were removed in...
Jetty 7.6.13.v20130916
Jetty 8.1.14.v20131031
Jetty 9.0.0.v20130308
.. as it was known to cause problems with LifeCycle startup.
The original reason for the parallel start was to improve startup performance.
Since Jetty 9.2.2.v20140723, the jetty-quickstart concepts were introduced that allows for a compile time scan of the webapp that produces a WEB-INF/quickstart-web.xml which allows for static load of the webapp (no bytecode scanning, no annotation scanning, no discovery of the Servlet spec components occur).
Related
I have a single instance of Jetty that runs 5 web-applications.
I want to un-deploy one of this application, my first thought was to delete the context from: $JETTY_HOME/contexts, it works but it's not clearing the whole application (I saw that some scheduled tasks are still running).
So, I need another way to un-deploy the application, or some kind of a clean-up after removing the context.
Thanks in advance.
Deleting the war file or associated context XML file is generally enough to clear the context. You can also run .stop() from JMX if you have that module enabled in your Jetty instance.
In regards to Quartz, Jetty itself does not interact with scheduled jobs. This can be handled by the webapp itself signaling Quartz that it is exiting. Alternatively you can implement a ServletContextListener to instantiate the Quartz jobs which will handle the removal of contexts gracefully.
Related: Can you undeploy applications from JETTY?
Is there a way to get the metrics for Jetty server, for example, the queue length, processing time, etc.
I looked at the QueuedThreadPool class, and tracked the the calling chain for getQueueSize, but I didn't find it got exposed.
Thanks.
"Queue Length" is a very vague term and can apply to many many different things.
As for seeing the metrics for Jetty, enable JMX, restart your server, and take a look.
Goto your ${jetty.base} and add the jmx module.
$ cd /path/to/mybase
$ java -jar /path/to/jetty-dist/start.jar --add-to-start=jmx
Once you have restarted, use the jmc command that comes with your JDK (or if you are using an ancient JDK use jconsole) and attach to the running Jetty process to see the various things exposed by Jetty for monitoring.
I am currently using Jetty 9.1.4 on Windows.
When I deploy the war file without hot deployment config, and then restart the Jetty service. During that 5-10 seconds starting process, all client connections to my Jetty server are waiting for the server to finish loading. Then clients will be able to view the contents.
Now with hot deployment config on, the default Jetty 404 error page shows within that 5-10 second loading interval.
Is there anyway I can make the hot deployment has the same behavior as the complete restart - clients connections will wait instead seeing the 404 error page ?
Unfortunately this does not seem to be possible currently after talking with the Jetty developers on IRC #jetty.
One solution I will try to use are two Jetty instances with a loadbalancing reverse proxy (e.g. nginx) before them and taking one instance down for deployment.
Of course this will instantly lead to new requirements (session persistence/sharing) which need to be handled. So in conclusion: much work to do in the Java world for zero downtime on deployments.
Edit: I will try this, seems like a simple enough solution http://rafaelsteil.com/zero-downtime-deploy-script-for-jetty/ Github: https://github.com/rafaelsteil/jetty-zero-downtime-deploy
I have a web application mostly written by others based on JSF 2, Mybatis, Spring 3 and tens of other libraries, running on Weblogic, it works and now I have to create a distinct command line application to schedule the running of some tasks already present in the web app.
I added a class with a main method in order to maintain only one codebase with a different build process to generate an executable JAR instead of a WAR. Using Spring's ClassPathXmlApplicationContext I managed to recreate the web application context, access the database beans and use them, but I'm stuck with a WSRR call which fails.
The commands:
GraphQuery graphQuery =
(GraphQuery)DataFactory.INSTANCE.create(TypeConstants.SR_URI, TypeConstants.TYPE_GRAPHQUERY);
graphQuery.setQueryExpression("/WSRR/GenericObject[#CFT_APPLIC='DS" + param + "']");
fail with a long stack, having the root exception
Caused by: java.lang.NullPointerException
at java.util.ResourceBundle.getBundle(ResourceBundle.java:960)
at com.ibm.ws.webservices.engine.resources.ProjectResourceBundle$Context.loadBundle(ProjectResourceBundle.java:474)
at com.ibm.ws.webservices.engine.resources.ProjectResourceBundle.getBundle(ProjectResourceBundle.java:372)
at com.ibm.ws.webservices.engine.resources.ProjectResourceBundle.getBundle(ProjectResourceBundle.java:341)
at com.ibm.ws.webservices.engine.resources.MessagesConstants.<clinit>(MessagesConstants.java:93)
I found that some classes and configurations are provided at runtime by the application server, and have no idea about how to replace them outside the application server.
The IBM redbook says (pages 120-121) that is possible to access a web service using a Java client, but requires a suitable EJB runtime.
How can I replicate needed EJB parameters outside the application server? I tried to use the Eclipse debugger to follow the execution of the application and extract them, but it fails, probably because the classes are loaded by Weblogic classloader.
There is an excellent article by Young Yang that explains how to use wsimport to create web service client artifacts that have asynchronous web service calls. Asynchrony requires that the WSDL has the tag
<enableAsyncMapping>true</enableAsyncMapping>
in its bindings section. If you are using the bottom-up approach with JAX-WS annotated Java classes you can't do this directly in the WSDL because the WSDL is a generated artifact on the web server. Instead you use build tools like Ant or Maven to include this binding when wsimport is executed on the WSDL.
The generated client artifacts have asynchronous method calls that return a
Future<?>
or a
Response
which is a Future.
My question after reading Yang's article is why not just roll my own asynchronous web service calls using Executors and Futures. Do the artifacts created by wsimport offer some advantage that I can't see over a roll-your-own approach?
If anyone has experience or insight with both approaches I would appreciate your feedback.
In theory, the generated asynchronous clients wouldn't need to block threads. By passing an AsyncHandler, the system can use NIO to register for an event when the web service call is complete, and it can call that handler. No threads need to block at all.
If you put your synchronous web service call into an executor, it will still end up blocking a thread until the result arrives, although at least this blocking is limited to the thread pool in the executor.
As soon as you have many hundreds of threads floating around, your system performance will degrade due to context switching.
Whether the web service library under the hood actually uses NIO is another matter. It doesn't appear to be required by the JAX-WS specification. Using JDK 1.6 and setting a break point server side, I set 100 clients off to call the server. Using JVisualVM I attached to the client and could see that it had created one new thread per call to the server. Rubbish!
Looking around on the web I found that Apache CXF supports limiting the pool of threads used in async calls. Sure enough, using a client generated with CXF and putting the right libraries on the classpath as discussed here, a retest showed that only 25 threads were being used.
So why use the jax-ws API rather than build your own? Because building your own takes more work ;-)
I know that it does not reach the prompted question, but just complementing one information included on question:
"Instead you use build tools like Ant or Maven to include this binding when wsimport is executed on the WSDL."
It is possible generate the asynchronous client by a adding a custom xml file using the option -b to the wsimport:
Example:
wsimport -p helloAsyncClient -keep http://localhost:8080/helloservice?wsdl -b customAsync.xml
The customAsync.xml content:
<jaxws:bindings
wsdlLocation="http://localhost:8080/helloservice?wsdl"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
<jaxws:enableAsyncMapping>true</jaxws:enableAsyncMapping>
</jaxws:bindings>
It is just one more way to generate asynchronous client beyond by using ant or maven :)