Embedded Jetty 8 hot deploy classes (using Maven) - java

I have a standard Maven webapp structure defined, and it uses Spring MVC.
I am using an embedded Jetty server (java class) for testing the application in development.
The code used to create the Jetty server is outlined below. If I make changes to any JSP files, the changes are immediately visible in the browser.
However if I change any class files, e.g Controllers, the changes are not hot deployed?
What do I have to do get this to work?
I have searched this and I think I need to use the class org.eclipse.jetty.util.Scanner and specifically the setScanInterval method, but not sure how to wire this up?
Here is the code to create the Server
String webAppDir = "src/main/webapp/";
Server server = new Server(8080);
WebAppContext webApp = new WebAppContext();
webApp.setContextPath("/");
webApp.setDescriptor(webAppDir + "/WEB-INF/web.xml");
webApp.setResourceBase(webAppDir);
webApp.setParentLoaderPriority(true);
HandlerCollection hc = new HandlerCollection();
ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
hc.setHandlers(new Handler[] { contextHandlerCollection });
hc.addHandler(webApp);
server.setHandler(hc);
return server;
Thanks in advance

For hot deployment you need to use the WebAppProvider and the DeploymentManager. Those you can configure to manage the scanning for changes and the reloading of the webapp. So it is clear, the WebappContext is not what manages the deployment of a webapp, it is merely the container class that is gets deployed so there is another mechanism that works outside of that which can handle the concepts of deploy/redeploy.
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-deploy/src/test/resources/jetty-deploy-wars.xml
You can take that chunk of xml there and convert into the java calls you need to do this embedded.
Or use something like the jrebel jvm plugin which provides for automatic class reloading.

Related

deployed webapps health in jetty server

I understand enabling JMX in jetty, we can fetch some information about deployed webapps.
Can Jetty also provide enough information to indicate that a given webapp is up and running, or some metrics that can be considered to identify the state of deployed webapps?
Perform a Jetty Server Dump.
https://www.eclipse.org/jetty/documentation/current/jetty-dump-tool.html
This will output the state of all relevant components within Jetty.
This can be accessed via the various "dump" methods on Server (choose the one that you want).
You can trigger this Jetty Server Dump within JMX as well.
Alternatively, you can ask each of the deployed webapps their running state.
Use the org.eclipse.jetty.util.component.LifeCycle interface, and the .isRunning() method.
The LifeCycle interface is available on all deployed webapps, even if they are an instance of WebAppContext (for war files), or ServletContextHandler for manually created webapps, or even ContextHandler for "bare metal" handling of requests.

Deploy war file in a grizzly server

I have spent a few days on this and I still did not find an answer (i did find questions asking for this)
I am coding with java, using a grizzly server (2.3 version) and I've managed to work with many kind of resources (restful classes, java servlets etc).
URI uri = new URI("http://localhost....");
ResourceConfig rc = new ResourceConfig();
rc.registerClasses(aResource.class);
GrizzlyHttpServerFactory.createHttpServer(uri, rc);
My goal though, is to load a whole war file and not individual classes but i have not find a way to do it.
So the question is 'how can i deploy and run a war file inside a grizzly server?'
According to the Grizzly Javadoc you do it like this:
Synchronous Web Server servicing a Servlet
GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
try {
ServletAdapter sa = new ServletAdapter();
sa.setRootFolder("/Path/To/Exploded/War/File");
sa.setServlet(new MyServlet());
ws.addGrizzlyAdapter(sa);
ws.start();
} catch (IOException ex) {
// Something when wrong.
}
However, as you can see, you first have to "explode" the WAR file; i.e. unpack it into the file system.
You seem to be using the Jersey ResourceConfig class. To make your approach work, I think you would need to do the following:
Unpack the WAR file.
Create a URLClassloader instance that loads from "/WEB-INF/classes" the JARs etc in "/WEB-INF/lib".
Register it by calling ResourceConfig.setClassLoader
For the record, classloading from a packed WAR file is more effort, and apparently gives poor performance. (If you want to see how to do it, Tomcat has this functionality ... disabled by default.)
It's not possible to deploy WAR files to Grizzly 2.x at this point in time.

Use Undertow to serve AngularJS

I would like to use Undertow as a simple web server for serving an AngularJS application. The rest services needed by the AngularJS application is served by Apache Camel so I would only need to serve the Angular App using Undertow.
I have read the documentation but cannot get it working, any ideas on what I am doing wrong?
Here is the code that I have now for starting Underow server
Undertow server = Undertow.builder()
.addHttpListener(8080, "localhost")
.setHandler(resource(new FileResourceManager(new File("../dist"),10))
.addWelcomeFiles("../dist/index.html")
.setDirectoryListingEnabled(true))
.build();
server.start();
File("../dist") is the problem. Use an absolute path or at least one without "..", then it should work.
(Undertow contains a sanity check comparing the computed file path for a resource with its canonical path, which breaks on "." and "..".)
You could also use ClassPathResourceManager.
ResourceManager rm = new ClassPathResourceManager(getClass().getClassLoader(), "dist");
ResourceHandler handler = new ResourceHandler(rm);

Embedding Jetty as a Servlet Container

I'm using Tomcat to serve my Java Servlets and it's kinda more for me. I just need to serve, Servlet Requests alone, no static content, neither JSP, etc. So I was looking for a Servlet container that can be embedded in my Application. I felt it if stripped Jetty and use it as a Servlet Container alone, it can be more scalable and occupying small memory footprint, [I don't need Jetty's 'Web Server' and other Parts]. So I've a few questions though,
How do I embed Jetty in my Application Code to serve Servlet Requests alone?
If I embed Jetty code in my Application Code, will I be able to easily upgrade Jetty Versions?
I got the Jetty code here, if I have to embed Jetty's Servlet Container in my App, which one should I use from the source,
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/snapshot/jetty-9.0.3.v20130506.tar.bz2 ,
jetty-9.0.3.v20130506/jetty-servlet or jetty-9.0.3.v20130506/jetty-servlets
I intend to serve API Requests with my Applications and I'm looking for Performance and Scalability as main constraints. And of course Servlet 3.0 support.
What you are looking for is running Jetty in an embedded scenario.
There's plenty of examples available showing how to tie together the various pieces you need to accomplish your goals.
Check out the embedded examples in the jetty source tree.
For the record, jetty standalone is really just jetty embedded with a few startup and classpath related bootstraps. It is the same code, and assembled in basically the same way.
Since you stated you want Servlet 3.0, have no interest in JSP, this is rather easy to setup. (JSP is trickier to setup, but possible).
For servlet 3.0 specific embedding, there's a complete example project hosted at github.
https://github.com/jetty-project/embedded-servlet-3.0
In short, you'll have the following initialization code.
package com.company.foo;
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.FragmentConfiguration;
import org.eclipse.jetty.webapp.MetaInfConfiguration;
import org.eclipse.jetty.webapp.TagLibConfiguration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.webapp.WebInfConfiguration;
import org.eclipse.jetty.webapp.WebXmlConfiguration;
public class EmbedMe {
public static void main(String[] args) throws Exception {
int port = 8080;
Server server = new Server(port);
String wardir = "target/sample-webapp-1-SNAPSHOT";
WebAppContext context = new WebAppContext();
// This can be your own project's jar file, but the contents should
// conform to the WAR layout.
context.setResourceBase(wardir);
// A WEB-INF/web.xml is required for Servlet 3.0
context.setDescriptor(wardir + "WEB-INF/web.xml");
// Initialize the various configurations required to auto-wire up
// the Servlet 3.0 annotations, descriptors, and fragments
context.setConfigurations(new Configuration[] {
new AnnotationConfiguration(),
new WebXmlConfiguration(),
new WebInfConfiguration(),
new TagLibConfiguration(),
new PlusConfiguration(),
new MetaInfConfiguration(),
new FragmentConfiguration(),
new EnvConfiguration() });
// Specify the context path that you want this webapp to show up as
context.setContextPath("/");
// Tell the classloader to use the "server" classpath over the
// webapp classpath. (this is so that jars and libs in your
// server classpath are used, requiring no WEB-INF/lib
// directory to exist)
context.setParentLoaderPriority(true);
// Add this webapp to the server
server.setHandler(context);
// Start the server thread
server.start();
// Wait for the server thread to stop (optional)
server.join();
}
}

Fastest way to deploy and run a Java WAR file?

Is there a simple, programmatic way to quickly "deploy" and run a standard Java WAR file for local testing without having to install and configure external software packages like Tomcat or Jetty? Ideally something like Jetty's embeddable features but specifically for WAR files.
Java 6 provides the convenient Endpoint class which makes it easy to quickly deploy and test web services, is there something similar for WAR files? For example:
AppServer as = new javax.iwish.AppServer("localhost", 8080);
as.deploy("/", new File("path/to/my.war");
as.start();
I asked too soon, it looks like Jetty does exactly what I need:
Server server = new Server(8080);
server.setHandler(new WebAppContext("foo.war", "/"));
server.start();
Remarkably close to my dreamed up API =D

Categories

Resources