How to accelerate re-start of spring application in Tomcat? - java

I have a big spring application with more than 1000 libraries.
When I do debug frequently not possible only adjust changes without restart, but restart takes a long time (about 5 minutes.) But 1000 libraries remain the same, I have changed only a few rows of code. Is it possible in some way to say to tomcat to apply only classes that were changed?
Thanks.

Use JRebel. In most cases, you can avoid redeploys. It replaces the class without having to restart the container.
Note that I'm not attached to ZeroTurnaround, except as a happy user.

Related

Expedite the develop / deploy / run cycle with Spring, Maven and Wildfly

I've just recently entered the Java world for a client of mine. I have 18 years experience as a .Net developer, but the Java side is new.
Coming from .Net, I'm used to expecting to be able to make a code change, compile my code and run it with a debugger attached all usually within sub 30 seconds, maybe 1 minute on large projects needing a full recompile.
I'm finding my current process with this Java project is taking me upwards of 5-6 minutes. Because of the long time and multiple steps, I find myself starting on other tasks or losing track of what I was doing.
Here is my current process for making a change and testing it:
Make code change
(~200s) Recompile code with Maven on the main Maven module mvn clean install. If I do -DskipTests I can save about 60 seconds here.
(~5s) Stop Wildfly server
(~5s) Copy .war file from myproject\target\myproject.war to c:\wildfly\standalone\deploy\
(~90s) Start Wildfly server c:\wildfly\bin\standalone.bat
Re-login to application (my session expired)
Attach debugger
Again, it is not only the amount of time required for each of these steps but the fact that there are so many steps and the waiting time in-between each makes for distraction as well - after all, who is going to sit and stare at a screen for a 3 minute compile? Whatever I go off to do, I am surely not going to return to that screen at the exact moment the compile is complete. There is going to be wasted time in there.
Further more, I'm repeating this process every time I want to make a single code change.
Is there a way to streamline this process? I.e.:
Is there a way to join some of these steps
Can I speed up the Wildfly boot process?
What will speed Maven up?
Can I do something like "Edit & Continue" which exists in .Net (i.e. live code changes).
Is there a way to get around having to have Wildfly reinitialize anytime I deploy a new war?
Disclaimer: My answer includes processes I personally use, thus it may not be the optimum or most popular solution. Anyway, these things tend to be bound to developer's personal preference.
Find below some recommendations that could speed up the development process.
Use a proper IDE for Java development
Using a popular java IDE can make development faster as it supports integration with build tools(Maven), Version Control Systems, Application Servers(Wildfly) and much more.
Popular choices are Eclipse, IntelliJ, Netbeans and much more.
Fast redeployment
As I said above, a proper IDE would support integration with application servers, Wildfly for your case. By using a Wildfly IDE plugin, you can speed things up as you do not have to wait for app server to boot every time you make a code change. IDE starts once the server and then applies your changes to the running instance.
Personally, I also prefer to use a standalone Wildfly installation instead of integrating it with IDE. To achieve fast redeployment I use hotswap agent. Note that you have to install DCEVM, an alternate JVM which however is not interfering with your main JVM.
Finally, to conclude it is understandable that you make a big turn from .NET to Java and you may feel lost at some points. I would advise to spend some time setting up your environment, and once you have finalised it and you feel comfortable, development will become much easier.
Why stop, move the archive and re-start the server ?
Check out the following maven plugin which will allow you to automate at least that part of it..
https://docs.jboss.org/wildfly/plugins/maven/latest/examples/deployment-example.html

Websphere Eclipse plug-in and Ant dev environment setup

We use Eclipse to develop and Websphere 7.0 to run our code. We use a plugin for Eclipse which allows you run run a copy of WAS locally and integrated with Eclipse. This works but it's not great. Each time I have to make a change I have to run my Ant script (5 mins.) then do my install into WAS and restart the app in WAS (another 5 mins). This is not efficient (actually it's downright annoying!)
What's the best setup Websphere allows, ignoring for a min what is easy to do etc. I want to know what to aim for. Obviously I would love to be able to save in eclipse then go to my browser and refresh the screen, am I mad?
I have looked at this about using Websphere's native Ant, and it is one avenue but I'm sure there's better.
Can I use jpda like I do when starting Tomcat and develop directly in the code? I will still need Ant when doing a full re-build as I have some Java file generation to do but for the in-process builds???
Thanks-in-advance for any and all help.
There is not just one straightforward single best answer as it depends a lot on the application you are doing.
If you rely on ant to make the build and that takes five minutes for any update you do then it may be hard to get away from that. You may not have to do it like that, you may be able to do incremental compilations (only compiling the updated classes) and that should be a lot quicker (but since I don't know anything about your application it is hard for me to tell you that this is a way forward for you). The updates you make in WAS and if that requires a total restart of the application depends on many different factors.
If I update only a jsp file it usually does not require a full application restart, but if you start to update the classes and definitely when you update your web.xml or something like that, a full restart of the application may be required.
The time it takes for you to restart your application depends a lot on what actions your application will perform when you start it up. If you have an application that takes five minutes to start up, then every restart will cost a lot. Is there something you can do to reduce the restart time in certain configurations? Can you divide your application into separate deployables to reduce the startup time for each individual application?
It all depends on your needs and requirements.
We used to have long startup times for our local servers, but since we had upgraded disks (SSD-disks) and enough memory the server startup time has been reduced by 80-90%.

How can I setup Tomcat running on a virtual machine to enable remote debugging as well as hot swapping synced file changes?

Apologies in advance for the lengthy explanation.
We have an large web application which uses a RabbitMQ server, a Tomcat webserver, a MySQL database, and a Hadoop environment. Most of the team uses Windows, and one uses Ubuntu, but we use CentOS for our deployment environment. We've recently started using vagrant and ansible to standardise environment configuration and deployment across multiple environments. This is part of a move to improve the quality of our application, and helps us to avoid failure between different environments.
We have most of it working now, and over the last few days I've been looking into replicating (or maybe even improving) our current development process with regards to building, running, debugging, and hot-swapping minor code changes without restarting the application. Our existing setup uses embedded Jetty (within eclipse), and we can run Jetty in either Run or Debug mode. With this setup we can place breakpoints, navigate to a relevant page, and when the breakpoint activates we can step through the code, drop frames off the stack to run through a method again, and even make minor changes to the code (within the rules of JVM hotswapping). This is, of course, fantastically helpful for us.
I want to replicate as much of this behaviour as possible except instead of an embedded jetty instance, I want to remote debug the tomcat instance on the virtual machine, but still be able to make changes to the code without needing to restart tomcat each time. I should probably point out at this point that I am aware of JRebel, but it has been deemed unfeasible for our team at this point in time.
At this point in time I have managed to automatically sync (using vagrant); 'src/main/webapp/WEB-INF', 'target/classes' (compiled by eclipse), and 'target/lib' (created by the maven copy-dependencies plugin'. These are all synced to the correct place on the vm, so that tomcat believes it is an exploded war. I have correctly setup Tomcat so that it runs in debug mode, and I have connected to it with eclipse, and successfully entered debug mode by placing a breakpoint. Making any changes to one of the synced files causes tomcat to restart the application and use the new file.
The only problems left are that I lose all my session data when I save a change to a file, and I have to wait for the re-deployment to complete and then repeat appropriate steps to get back to my breakpoint. This is obviously a big waste of time.
So after that lengthy explanation, my questions are:
Has anyone managed to achieve what I'm trying to do?
Is what I'm trying to do even possible?
If so does anyone have any tips to help me finish my configuration?
Can I do hot class replacement without triggering a context reload?
Any help would be greatly appreciated and sorry for the essay! :)

How to update application without stopping Java EE server?

I have an application running on a JBoss server. We need update the application time to time.
However, the JBoss is not allowed stop(restart) during update for business reason. How do I handle this tricky situation? Thanks!
2 cases:
If the application is deployed in
multi servers in cluster mode.
If the application is deployed in a
single machine.
If you can't stop the application even for a moment then you probably need to:
To run both versions at the same time.
Direct new users to the new version and allow existing user sessions to continue against the old version
To be able to detect that the old version is no longer in use and hence can be stopped.
Each of the above is, in principle, possible but specifics of the applcations can present serious obstacles.
Many organisations simply take the view that there can be a small hiatus in service, for example at 2:00 AM on a Sunday morning. They warn users "system going down", then stop the old version and start the new. This is much simpler than providing 100% up-time.
One trick with this approach is that it may be possible (I know it can be done in WebSphere, don't know about JBOSS) to deply the new version of the app but not activate it. When an app takes several minutes to deploy and start this can shorten the down time.
It's a common problem, and web apps can't really "updated" at runtime (unless it's a hotdeploy environment). Perhaps you want something like LiveRebel?
LiveRebel
Would you like to update your
application in production with zero
downtime? Avoid the tedious and
error-prone application update
roll-outs? Roll back unsuccessful
updates with a press of a button? Then
sign up to receive an invitation as
soon as it’s available.

How can I do to load all the resources when starting the app?

Java loads the resources as they are needed. This make my tiny small desktop application to be very slow when opening a window.
How can I do to load all the resources when starting the app? Is something related to classloaders?
EDIT: does this code work if the files are inside a jar?
EDIT2: Note that the aim is not to reduce the startup time, but to reduce the time of new windows opening after the app is started. I want all resources to go to the memory and stay "ready for use", so after loaded the app will run faster the user's commands.
Java loads the resources as they are needed.
Actually, it is more complicated than that. If you have a class A that statically depends on a class B that statically depends on a class C, then loading A will trigger eager loading of B and C and so on. But some libraries (and I think AWT and Swing do this) internally use the Class.forName(...) method to lazily load implementation classes. This reduces the number of classes that are loaded initially, and (ideally) avoids loading code that your application will never use.
How can I do to load all the resources when starting the app?
I suppose that you could create explicit static dependencies to defeat the laziness above, but that probably won't make your application's initial window appear more quickly. A better strategy would be to try to use more lazy loading to reduce the amount of code that needs to be loaded to get the initial window visible. But this needs to be done judiciously. If you lazyily load classes that are needed for the initial window, you may actually make startup slower.
Compiling to native code (using GCJ for example) is another alternative, but this has various downsides; e.g. larger binaries, more native library dependencies, portability issues, (possibly) slower execution speed for a long running application.
Re your EDIT: I think that code will "work", but I don't see how it could possibly speed up your application's startup.
If you mean also other resources than classfiles then you could use the proxy pattern to delay loading (lazy loading) until you really need the resources.
The problem is harder: The code is initialized if it is used, which can be seen even on the method level. So you have to run it to load it.
The only other possibility is to buy Excelsior Jet, which does the compile step for you (and returns a nice .exe as a side effect).
EDIT: You can reduce your runtime by Class.forName()ing all your classes during startup, and having everything loaded when its needed. Please note that for having everything really fast, the code must have been run, so maybe you can open, but hidden, all windows, the close them, and then really show the main window from which all other windows are opened. Sadly this will make your app startup really slow. But it can even be done in background, while the user decides what to do next.
On Windows 7 and had a similar issue with Java Applications Client Side. Anything that extended any Gui (Frame, JFrame, etc...) would start to take over a minute to run and load from only taking a few seconds.
Traced it down to IIS running in the background (after an update?).
Stopping its service from Control Panel\Programs\Programs and Features - Turn Windows features on and off.
And now the Java Applications are loading in a couple of seconds again.
Hope other people find this helpful. :-)

Categories