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

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

Related

How to speed up the app startup on a Java app using Heroku and CleverCloud?

Context: I am learning to code with a course run by my country's government. We are using Angular, Java Spring Boot and SQL to create a portfolio. They did not go into much detail on different things, and they pointed us to Google (and Stack Overflow), as well as cooperation between students, for any doubts. I managed to create an app, and is currently hosted on Firebase (frontend), Heroku (backend) and CleverCloud (database), with the free versions of each.
When running the app locally, it starts in around 10 seconds. When running the app in Heroku or doing clean and build in Apache Netbeans while connected to CleverCloud, it starts in around 2 minutes. I would like to reduce the start up as much as possible. The obvious solution would probably be to use a non free version of Heroku and not let the app stop, but given both my country and the course aiming for the free version, that is not an option.
What I tried:
Deleting unused imports on entities and adding the "Excluding test
dependencies" part in this Heroku guide:
https://devcenter.heroku.com/articles/reducing-the-slug-size-of-java-applications,
but after doing a clean and build in Apache Netbeans, the load time
was around 2 minutes, and it took like another minute to do other
processes that were not there before. I ended rolling back the changes.
Added a loading screen to the frontend to tell users that Heroku takes 2 minutes on startup, and a timeout of like 1800000 on the HTTP calls made from the frontend, but the HTTP call still crashes after like a minute, making it so user have to refresh the page and wait.
I would like, as the app is going to be checked at some point, to either have the app running nonstop on weekdays on workhours or for it to start fast. I saw some pages like https://kaffeine.herokuapp.com/ that ping the app, yet I dont know how to use them o if I can set them for free to be used on weekdays and workhours.
Given the startup is slow on both Heroku and while doing a clean and build in Apache Netbeans while connecting to CleverCloud, I dont even know if the issue is on Heroku itself. As someone who is completely new to coding, and its exposure has been a "do this" without much explanation, this is kinda frustrating. I have seen something called "cron", but I dont understand how they work or to create them, or if they would work on a Java app that only supports CRUD (maybe doing this cron thing on the frontend, but still I dont know anything about them).
TLDR: Are there any ways to speed up the build or start up of a Java app, or guides to autoping free Heroku apps on weekdays and workhours for dummies?
Sorry if the question is obvious, as I am a total beginner that had to rely on code along guides and videos.
For the Free & Hobby version on Heroku you application on Free version will go to sleep which after arriving on the site will take a while to load up.
Sleeps after 30 mins of inactivity, otherwise always on depending on your remaining monthly free dyno hours.
For 7 bucks a month you can remove this restriction and get more power Hobby version - I think it's totally worth it and I use this for my personal projects quite a lot. https://www.heroku.com/pricing
If you use something to ping Heroku to keep it alive you will run out of dyno hours (hours that your app can run) and even then the free tier will have hard time running applications.
Also Heroku supports SQL (Postgres) so having db, frontend and backend in the same place is a bonus. Everything runs smoothly, environment variables and automatic deploys are easy to set up.
If it's your first time on AWS you could also use free tier over there for some time and deploy using elastic beanstalk. But AWS infrastructure can be overwhelming for one simple free project - gotta watch out when they start charging you.

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! :)

Website developmet with JBOSS

In my company there are around 30-40 developers and all of them are working on same website developmet project. Project is devided in many modules. My problem is every developer has run his own JBOSS to run his JAVA code. With Ant, they build the Ear file and deploye them on JBOSS which is running on their local desktop. This require huge memory and slow down the desktop.
Isn't possible if we can run the JBOSS on different server machine and all developer use this machine to run and test their code simultaneously? Hope you guys understand my question?
Thanks in advance.
You can set up a continuous integration server like Jenkins. With Jenkins you have different "projects". Each project builds the code and runs an instance of JBoss.
With Jenkins you can have a different project for each developer (if that's what you want) and you can get the added benefits of Jenkins compiling and running unit-tests each time a developer checks in code.
it is possible.you can achieve this by running the JBOSS Application Server on a particular IP.to do this you have to use ./run.sh -b followed by the IP Address of the machine on which you want to run the application server.with this your server is ready.now every client has to connect to the server with the help of that IP address.for this you replace the loopback address(127.0.0.1) with the IP address on which application server is running.
You can but with many developers all together it can get tricky.
It is possible to run a single instance of jboss but then you run into problems with either hot deploys, slowing work and cross contaminating if different devs work on the same code, or no hot deploys, in which case the server has to be shutdown every time an app is deployed/changed. In a testing environment this doesn't work very well.
The other way would be to run a separate instance for every dev to run tests on but this can get very cost intensive in both money and server resources. You also have a nightmare when you try to merge changes from these various environments.
Some good organization might help. We run three layers:development, staging, production. Development is purely for your developers. Bug tracking and testing is handled in staging while production is for user and customer evaluations(assuming the product hasn't been rolled yet). Use a good repository to code up changes from local machines to development, then the admins roll groups of changes to staging. It doesn't really solve your problem of the memory on local machines but I thought I would try and help out with some enterprise level stuff.
One quick fix would be to put tons of RAM on each machine, its dirt cheap anyway. Then set your server memory settings up way higher. That will reduce your cpu loads a bit and reduce the number of time you see the dreaded permgen error from too many hot deploys

Websphere Application Server - What on earth will it take to start any fast?

I am using Rational Application Developer v7.0 that ships with an integrated test environment. When I get to debugging my webapp, the server startup time in debug mode is close to 5-6 minutes - enough time to take a coffee break!
At times, it so pisses me off that I start cursing IBM for building an operating system instead of an app server! Spawning 20+ processes and useless services with no documented configuration to tuning it, to starting any faster.
I am sure there are many java developers out there who would agree with me on this. I tried to disable the default apps and a set of services via my admin console, however that hasn't helped much.
I have no webservices, no enterprise beans, no queues, just a simple web app which requires a connection pool. Have you done something in the past to make your integrated test environment, start fast in debug mode and there by consume less RAM?
UPDATE:
I tried disabling a few services (internationalization, default apps etc...) and now the WebSphere server went from bad to worse. Not only doesn't it take horrifying startup time, it keeps freezing every now and then for up to 2 minutes. :-( Sounds like, optimization is not such a good thing, always!
The best way to debug server code is to use remote debugging.
First you need to add the following to the JVM params in the server start script:
-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
This will cause the JVM to listen on the specified port, then from your IDE you can start a remote debug session against that port and debug as if the code was running in the same process.
Working this way prevent you restarting the server so frequently and hence side-steps your problem with Websphere's start-up time.
You can get some odd results if the binaries on the server and the source in the IDE get out of sync but on the whole that's not a problem.
One of the main reasons is that you have a large application with many modules, classes, manifests, XML descriptors so on, and the fact that Websphere application server start up process is single threaded per se (thus each application may be started in a separate thread if they has equal weight). One other reason is that the Eclipse EMF and JST frameworks are very I/O intensive during startup and publish/deploy.
One other reason for the tedious start up is the annotation scanning which will occur during publish/deploy. This annotation scanning can be controlled and modified in a various ways. Look at this site:
http://wasdynacache.blogspot.se/2012/05/how-to-speed-up-annotation-processing.html
First of all, examine and evaluate your hardware, both CPU, memory and HDD. Is your processor/s running 100% for a long time during start up? If so, the processor may be too weak. Is paging occur? then you may have to put in some more RAM. The Websphere/eclipse JST and EMF frameworks are very I/O intense so you should consider to invest in a SSD disc. You should also make sure that other processes on your machine (virus protection software etc.) don´t steal hardware resources from the Websphere java processes.
So for the hardware:
1. Processor - a pretty fast one, since the publish and the startup is mostly singlethreaded you do not need that many cpu cores
2. Memory - You will at least need 512Mb of physical RAM, this depends of the size of your application of course.
3. Storage - I would definitely go for a fast SSD since the underlying eclipse framework is I/O intensive.
Here are some tricks to reduce the footprint of the start up phase. Please before applying these settings make sure that you record a baseline start up so that you can observe the difference in start up, i.e. the reduced start up time.
JVM args : -Xverify:none -Xquickstart -Xnoclassgc -XX:+UseNUMA -XtlhPrefetch -Xgcthreads4 (I got 4 virtual processors installed on my machine)
Extend the heap size to match the demands of your application.
Disable the autostart of the application to reduce publish time.
Disable PMI and unnecessary tracing.
Profile your application during startup and fix bottlenecks if found any.
Other JVM arguments that may gain performance:
com.ibm.cacheLocalHost=true
com.ibm.ws.classloader.zipFileCacheSize=512
com.ibm.ws.classloader.resourceRequestCacheSize=1024  
com.ibm.ws.management.event.pull_notification_timeout =20000
com.ibm.ws.amm.scan.context.filter.packages=true
org.eclipse.jst.j2ee.commonarchivecore.disableZip=true
Jvm arguments that will make the Websphere application server to stop immediately:
com.ibm.ejs.sm.server.quiesceTimeout=0
com.ibm.ejs.sm.server.quiesceInactiveRequestTime=1000
Webcontainer properties:
com.ibm.wsspi.jsp.disableTldSearch=true
com.ibm.wsspi.jsp.disableResourceInjection=true
JVM arguments that may be specified eclipse.ini (Note that the heap parameters is configured according to the conditions of my environment)
-Dcom.ibm.ws.management.event.max_polling_interval=5000
-Xquickstart
-Xverify:none
-Xmxcl25000
-Xjit:dataTotal=65536
-Xcodecache64m
-Xscmx48m
-Xnolinenumbers
-Xverify:none
-Xmnx64m
-Xmx1446m
-Xmnx64m
-XX:+UseCompressedOops
-XX:+UseNUMA
5 to 6 mins is not normal. I use RAD and WAS everyday and get decent startup times. Which version of WAS are you running and how much RAM do you have?
If you share several workspaces and projects for a same WAS profile, consider creating a new WAS profile for your workspace.
You probably tried that but here's a simple check list of things to try on first hand. Make sure that your server settings in RAD has the following options enabled:
Optimize server for testing and developing
Run server with resources on the workspace
Minimize application files copied to the server
Uncheck "Enable universal test client" if you don't need it.
In the admin console you can verify some server settings such as
Run in development mode
Parallel start
Start components as needed
You can also uninstall the ivt app that comes installed by default when creating a new WAS profile. Then the usual things such as a drive that is not too fragmented and a pagefile size that is properly set.
And one last thing that you probably know already, republish to your server instead of restarting it.
That's one reason why Spring was born.
You don't even have to give all the niceties like JMS, remoting, etc. You'd be better off with Tomcat, ActiveMQ, and OpenEJB.
Anything but WebSphere.
There's some hints and tips for tuning RAD 6 on developerworks that may help, many of these also apply for RAD 7.
I have seen a similar list for RAD 7, I'll post it if I can find it.
I did find some tuning tips for Portal on RAD 7.
I would say my experience with the test environment has been suboptimal. I now tend to use Tomcat/Pluto configured for remote debugging with an External launch configuration to manage it from within bare Eclipse and rely on having appropriate JNDI configurations to abstract the underlying server.
If you are coding to the relevant APIs it shouldn't matter for development purposes that you're not on Websphere. If you do have a Webpshere specific issue you can always crank up the beast to debug it.
If you have no EJBs, no JMS, etc., just deploy under a standalone servlet container such as Tomcat or Jetty, you'll be amazed how fast it is :-), being ironic here but it's true!
If the connection pool really is the only appserver feature you use then why don't you simply use apache commons dbcp (http://commons.apache.org/dbcp/) drop webfear alltogether and use jetty instead. That should reduce your startup time to about 5 seconds. You can then later easily switch to websphere again for your production environment if you should really feel the need to.
WAS V7 addresses some of these problems by allowing you to configure what starts up when the app server starts up.
So if and when you migrate to WAS V7 you might seem some improvements in this space.

Categories