I am writing a Java EE application, using Jetty as the app server for convenience during development. Although (re)deployment is fast, I'd like if it was possible for Java code changes to be reflected immediately in the running server without restarting. (I'm already using the useFileMappedBuffer setting to see immediate changes to statically served content).
I've seen questions about using the Maven Jetty plugin and setting scanInterval in order to redeploy a web context, but that's not what I want to do. My Jetty server is started from within a Java application in Eclipse and I'd like code changes to be immediately reflected in the running server, as is possible with ordinary Java applications in Eclipse. I'm running the code "in place", i.e. not building and deploying a WAR file first.
I realise that web apps have their own class loaders in order to conform to the servlet spec, but I don't mind risking non-standard behaviour to get changes deployed more rapidly in development. I've tried using WebAppContext.setClassLoader to set the classloader to a "normal" classloader but to no avail.
Is it possible to do what I want? I believe JRebel claims to do it, but what's it doing that I'm not?
If you connect to Jetty using remote debug from Eclipse, Hot code replace should be possible.
Remote debugging is enabled by adding following to Jetty start script:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8787
Even the ordinary Java application needs to be restarted to see code changes.
Basically your options are:
Restart Jetty (you said you don't want that).
Make Jetty scan for application changes and allow hot redeploy if changes are detected (you said you don't want that).
Attach a remote debugger which then does hot-swap your code changes (see answer of Amila). This is limited to method body changes and therefore not really useful.
Use JRebel which provides a useful hot-swap implementation and also can pick up configuration changes for many frameworks.
Use a web framework which implements a proprietary hot-swap implementation based on throw-away-classloaders (e.g. Tapestry or Civilian).
Related
I'm currently looking into what better ways there are for deploying/setting up webapps locally after code changes and database changes.
So far I've seen the following tools/ways come by, and attempted each of them:
ANT build target that compiles, makes a jar, a war file and deploys that to the tomcat folder
Gradle build in combination with the tomcat plugin, which already does a bit of a better job than option #1
Good ol' fashioned command line
Setup run configuration within Intellij to do the deployment for you
Write shell script and call this via command line (haven't tried this)
To be honest I'm not finding each of these the ideal solution. I find option #4 the easiest as it allows me to, via a short-cut, easily deploy my changes and continue. This has however not given me an option for database changes yet, probably just me that missed it.
My question is mainly what tools/ways are you guys using in order to achieve an easy and maintainable development environment? What considerations come with those?
Well, let me tell you what I do for local web app setup.
In your favorite IDE(eclipse in my case) i'll configure the application server plugin(tomcat or webpshere) from Eclipse marketplace.
This setup will help to auto publish code changes to the server whenever I make a change in the application. I use Maven build tool for the application packaging. However I'm not sure about the database side.
For the people that were wondering how I ended up doing and found the best to work for me.
I currently have configured my IntelliJ IDE in such a way that the tomcat instance is linked and can be properly controlled and deployed, including debug, from within IntelliJ itself. This allows me to, via an easy shortcut, instantly populate any resources changes (css, javascript, front end) or redeploy or even restart the server. Especially with a small application this works very well.
It is yet to be determined whether this would still work with a multi-module setup and a larger project size.
Should you want more information on how this configuration can be achieved, feel free to send me a direct message.
The Application is Running on Tomcat Server using java.I dont want to stop the Server everytime there is a Java change. The build System is heavily reliant on Shell Scripts, so i cannot use any Java IDE to do normal HotSwap.
Now, Is there any otherway i can Hot swap the file?
I have used JRebel for this purpose on several java projects. It can reduce redeploy times considerable.
One way would be to use the Tomcat Management Web User Interface. You can easily script commands to the WebUI using curl.
There are also Ant tasks for Tomcat management operations.
Reference:
http://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html
Examples:
Tomcat 7 tomcat-users manager-script example for /deploy
Tomcat manager remote deploy script
If you are looking for some kind of graceful update of your applications, you can take a look at Tomcat's Parallel deployment. With that option, you can update application without stopping current open sessions. The server will start new sessions on the new application versions while older one wont be renewed on the older.
What you are looking for is a Development Mode which allows you to swap the Application at runtime with a new version. This is usually useful for development while not practiced in the production, hence it is called "development mode".
See How to Install Apache Tomcat for Development Mode.
More on this also in Restart tomcat when a class file is changed?.
See the Documentation, search for reloadable:
reloadable
Set to true if you want Catalina to monitor classes in /WEB-INF/classes/ and /WEB-INF/lib for changes, and automatically reload the web application if a change is detected. This feature is very useful during application development, but it requires significant runtime overhead and is not recommended for use on deployed production applications. That's why the default setting for this attribute is false. You can use the Manager web application, however, to trigger reloads of deployed applications on demand.
The ide used is :IBM Rational® Software Architect™ for WebSphere® Software
Version: 7.5.5.3
The app server used is Wbesphere 6.1.
I am posting this question because my server takes about 7 to 8 minutes to start.
So even if i make a small change ,i have to wait 10 minutes to test the change in my application.So is there a way where i can make changes to my java code and test them without restarting the server.
Suggestions appreciated !!!
Note:
I am not supposed to use any build tool in my environment.
There is a plugin called JRebel that let's you do changes without restarting the server.
Dynamic Code Evolution VM is open source alternative to JRebel you can try for reloading classes. It will do entire class redefinition, even reloads changes done to class hierarchy.
Theoretically reloading classes is build into the JVM, although most implementations (specifically Oracle's) only reload (hot swap) as long as you only change code inside the body of a method.
The other problem is that in Eclipse the WTP adapter has to cooperate and only deploy the changed class definition (incremental deploy). GlassFish for some reason has always been a big opponent of incremental deployments, and hence its WTP adapter restarts the server after making even the most tiny change.
JBoss used to be a proponent of incremental deployments, but after AS 7 ("everything has to be different"), they are now a follower of the "restart the server" school as well.
Yet another issue is that plain class loading is often only one part of the story. In EJB, JSF, JPA and many other frameworks classes also have to be re-registered by the framework, caches have to be cleared, etc
This all is where something like JRebel comes it. It reloads nearly all kinds of changes to classes. It also works independently from the WTP adapter thus freeing you from the whims of the server vendors regarding if restarting is hip today and lame tomorrow or exactly the other way around. JRebel also has knowledge and plugins for many frameworks.
Unfortunately JRebel is not perfect and occasionally things will just fail, but overall it works pretty well.
One other piece of advice: most modern application servers start up in a second on relative fast hardware and with a small application or a some 10 seconds for a larger app. With those and session serialization you almost don't need things like JRebel anymore.
Problem: I have a standalone Java app (henceforth known as "the agent") that runs as a service on internal company servers. It acts as a remote agent for some central servers. As the agent gets deployed in more places, managing them is getting more complicated. Specifically: pushing updates is painful because it's a fairly manual process, and getting access to the logs and other info about the environments where the agents are running is problematic, making debugging difficult. The servers under discussion are headless and unattended, meaning that this has to be a fully automated process with no manual intervention, hence Java Web Start isn't a viable solution.
Proposed solution: Make the agent phone home (to the central servers) periodically to provide agent status and check for updates.
I'm open to other suggested solutions to the problem, but I've already got a working prototype for the "status and self-updates" idea, which is what this question is focused on.
What I came up with is actually a separate project that acts as a wrapper for the agent. The wrapper periodically calls the central server via HTTP to check for an updated version of the agent. Upon finding an update, it downloads the new version, shuts down the running agent, and starts the new one. If that seems like an odd or roundabout solution, here are a few other considerations/constraints worth noting:
When the wrapper gets a new version of the agent, there may be new JAR dependencies, meaning class path changes, meaning I probably want to spawn a separate Java process instead of fiddling with ClassLoaders and running the risk of a permanent generation memory leak, which would require manual intervention--exactly what I'm trying to get away from. This is why I ended up with a separate, "wrapper" process to manage the agent updates in my prototype.
Some servers where the agents are deployed are resource-limited, so any solution needs to be low on CPU and memory usage. That makes me want a solution that doesn't involve spinning up a new JVM and is a stroke against having a separate wrapper process.
The agent is already deployed to both Windows and RHEL servers, so the solution must be cross-platform, though I wouldn't have a problem duplicating a reasonable amount of the process in batch and bash scripts to get things rolling.
Question: As stated, I want to know how to make a self-updating Java app. More specifically, are there any frameworks/libraries out there that would help me with this? Can someone with experience in this area give me some pointers?
If your application is OSGi based, you could let OSGi handle bundle updates for you. It is similar to the wrapper approach you suggest, in that the OSGi container itself is "the wrapper" and some of it won't be updated. Here's a discussion on this
Different solution: use (and pay for) install4j. Check out the auto-update features here
No need for wrapper (save memory) or java web start (adds more restrictions on your application), simply let a thread in you application check periodically for updates (e.g. from cloud) and download updates if available, then code these two calls in you application:
launch a shell script (.sh or .cmd) to update your artifacts and launch your application after few seconds pause in the script(to avoid having two instances of your application at the same time).
Terminate your application (first instance)
The script can overwrite needed artifacts and re-launch your application.
enjoy !
Have a look at Java Web Start.
It is technology that's been part of Java since... 1.5? maybe 1.4? and allows deployment and install of standalone Java-based apps through a web browswer. It also enables you to always run the latest app.
http://www.oracle.com/technetwork/java/javase/overview-137531.html
http://en.wikipedia.org/wiki/JNLP#Java_Network_Launching_Protocol_.28JNLP.29
also see this question: What's the best way to add a self-update feature to a Java Swing application?
It appears as though Webstart is the only built in way to do this at the moment.
I am developing a GWT application that uses EJB and other Java EE 6 technology as the backend. I am currently using the GWT 2.0 plugin for Safari.
When I change my GWT client side code and save in my IDE (NetBeans), all that's required is a simple reload in the browser for the changes to become active. That works great!
However, often I work on the server-side (the EJBs, GWT server code, etc) and then something in on the GWT client side. Any changes done to the server-side do not appear to incrementally deploy to the Glassfish V3 server. Currently I close the GWT Development Mode application, and then recompile the EJBs, and then go back into GWT Development mode. That is tedious.
Any better way of doing this? I tried the "deploy on save" option in NetBeans but it does not seem to do the trick.
The trick is to create an exploded ear directory (instead of an ear file) and deploy that in your application server. It works in JBoss and Weblogic, and should work in glassfish, but haven't tried it.
The idea is that you don't use any archives at all. In you war directories, create a WEB-INF/classes folder, and configure your IDE to write the class files in this directory. That way, when you change a java file in your IDE, it will write to your classes directory and the JVM will hot-deploy your classes.
There are some restrictions with this approach. If you change a method signature or add a class or new method, JVM cannot pick it up. In such cases, touching web.xml redeploys the WAR. This in itself is an improvement from restarting the entire application server.
It takes an hour or two to get the right setup, but after that you will just love it.