Rebuilding the WHOLE Java application everytime I make a change - java

I am new to building Java web applications & WAR files. I am working with a fairly large web application that is built on Java & JSP pages. We have a ANT file that will re-build the entire application every time a single change was made. I want to know if it is possible to only re-build the part of the application that was modified instead of the whole entire project.
Testing is a 10 minute process because I will make a change, shutdown Tomcat, run the ANT script, start Tomcat, re-load application in browser which now takes 7min to do load for the first time after a re-build (I'm also curious to know what it's doing here?)...Basically complete hell for testing.
If anyone could suggest a better testing strategy I would be awesome! Also maybe anyway we would just have the ANT script re-build only modified classes.

There are several things one can do.
One can modify jsp in the tomcat/temp directory. The change will be available immediately without any recompiling/reloading
One can use the remote Tomcat debugging (from Eclipse). This debugging allows one to change the source code and this change will be propagated to Tomcat immediately
The best way to organize your ant script is to separate compiling into several jars and then creating a war file. Then recompilation for one change will happen only in one jar.
It is not required to restart Tomcat under redeployment if you specify reloadable=true for the context

Related

What's the best way to implement a shell command into my java project

I have a JavaFX/ Maven project.
While developing I sometimes need some Java code to run just once.
In my special case I have a directory containing configuration or temp files on the user's disk. This directory and its files will be created by the app when a new user is starting the app for the first time. In production, it will never be necessary to delete these files.
But in development, I sometimes change something in the file generation code. For example when I'm adding new configuration options. To test that I have to delete the directory manually and let my application regenerate everything to check if it still works.
In my years of coding, I had cases like that several times. And what I used to do was creating a method for this special task. Then I'm calling it from the main method and run the app.
I am sure I am not the only one and I am sure there is a better possibility.
I thought of creating some kind of command for the terminal to run my method.
Maybe a configuration in my IntelliJ which would call the method.

Automated updates for Java applications [duplicate]

I would like to implement a java application (server application) that can download a new version (.jar file) from a given url, and then update itself at runtime.
What is the best way to do this and is it possible?
I guess that the application can download a new .jar file and start it. But how should I do the handover, e.g. know when the new application is started and then exit. Or is there a better way to do this?
The basic structure of a solution is as follows:
There is a main loop responsible for repeatedly loading the latest version of the app (if required) and launching it.
The application does its thing, but periodically checks the download URL. If it detects a new version it exits back to the launcher.
There are a number of ways you could implement this. For example:
The launcher could be a wrapper script or binary application that starts a new JVM to run the application from a JAR file that gets replaced.
The launcher could be a Java application that creates a classloader for the new JAR, loads an entrypoint class and calls some method on it. If you do it this way, you have to watch for classloader storage leaks, but that's not difficult. (You just need to make sure that no objects with classes loaded from the JAR are reachable after you relaunch.)
The advantages of the external wrapper approach are:
you only need one JAR,
you can replace the entire Java app,
any secondary threads created by the app, etc will go away without special shutdown logic, and
you can also deal with recovery from application crashes, etc.
The second approach requires two JARs, but has the following advantages:
the solution is pure Java and portable,
the changeover will be quicker, and
you can more easily retain state across the restart (modulo leakage issues).
The "best" way depends on your specific requirements.
It should also be noted that:
There are security risks with auto-updating. In general, if the server that provides the updates is compromised, or if the mechanisms for providing the updates are susceptible to attack, then auto-updating can lead to a compromise of the client(s).
Pushing a update to a client that cause damage to the client could have legal risks, and risks to your business' reputation.
If you can find a way to avoid reinventing the wheel, that would be good. See the other answers for suggestions.
I am currently developing a JAVA Linux Daemon and also had the need to implement an auto-update mechanism. I wanted to limit my application to one jar file, and came up with a simple solution:
Pack the updater application in the update itself.
Application: When the application detects a newer version it does the following:
Download update (Zipfile)
Extract Application and ApplicationUpdater (all in the zipfile)
Run updater
ApplicationUpdater: When the updater runs it does the following:
Stop the Application (in my case a daemon via init.d)
Copy the downloaded jar file to overwrite current Application
Start the Application
Cleanup.
Hope it helps someone.
I've recently created update4j which is fully compatible with Java 9's module system.
It will seamlessly start the new version without a restart.
This is a known problem and I recommend against reinventing a wheel - don't write your own hack, just use what other people have already done.
Two situations you need to consider:
App needs to be self-updatable and keep running even during update (server app, embedded apps). Go with OSGi: Bundles or Equinox p2.
App is a desktop app and has an installer. There are many installers with update option. Check installers list.
I've written a Java application that can load plugins at runtime and start using them immediately, inspired by a similar mechanism in jEdit. jEdit is open source so you have the option of looking to see how it works.
The solution uses a custom ClassLoader to load files from the jar. Once they're loaded you can invoke some method from the new jar that will act as its main method. Then the tricky part is making sure you get rid of all references to the old code so that it can be garbage collected. I'm not quite an expert on that part, I've made it work but it wasn't easy.
First way: use tomcat and it's deploy facilities.
Second way: to split application on two parts (functional and update) and let update part replace function part.
Third way: In your server appliction just download new version, then old version releases bound port, then old version runs new version (starts process), then old version sends a request on application port to the new version to delete old version, old version terminates and new version deletes old version. Like this:
This isn't necessarily the best way, but it might work for you.
You can write a bootstrap application (ala the World of Warcraft launcher, if you've played WoW). That bootstrap is responsible for checking for updates.
If an update is available, it will offer it to the user, handle the download, installation, etc.
If the application is up to date, it will allow the user to launch the application
Optionally, you can allow the user to launch the application, even if it isn't up to date
This way you don't have to worry about forcing an exit of your application.
If your application is web based, and if it is important that they have an up to date client, then you can also do version checks while the application runs. You can do them at intervals, while performing normal communication with the server (some or all calls), or both.
For a product I recently worked on, we did version checks upon launch (without a boot strapper app, but before the main window appeared), and during calls to the server. When the client was out of date, we relied on the user to quit manually, but forbid any action against the server.
Please note that I don't know if Java can invoke UI code before you bring up your main window. We were using C#/WPF.
If you build your application using Equinox plugins, you can use the P2 Provisioning System to get a ready-made solution to this problem. This will require the server to restart itself after an update.
I see a security problem when downloading a new jar (etc.), e.g., a man in the middle attack. You always have to sign your downloadable update.
On JAX2015, Adam Bien told about using JGit for updating the binaries.
Sadly I could not find any tutorials.
Source in German.
Adam Bien created the updater see here
I forked it here with some javaFX frontend. I am also working on an automatic signing.

Netbeans deploy on save: how is it supposed to work?

I'm trying to setup deploy on save (or compile on save, or whatever I should setup) correctly in Netbeans.
I'm trying to achieve this:
1) hot-replace some class when needed if the structure didn't change (push the button, new code replacing the old one)
2) copy my jsf pages (.xhtml) to glassfish on save
1) works most of the time; it sometimes doesn't after I deploy many times (why?), or if Netbeans decides for whatever reason that it should deploy the whole thing (it does... sometimes)
2) works in some project, not in others
Seems like black magic.
How is it supposed to work? I can't seem to have 1) and 2) working on the same time for all my projects. How should I configure that? I must have done something wrong, I just need to know what the checklist is.
I opened this some time ago: https://netbeans.org/bugzilla/show_bug.cgi?id=218806
UPDATE: this is a maven project
This update from the Jira issue should clarify it:
At the moment there are two important features:
--> Compile on Save (will be referred as CoS) which basically means that your java files are compiled immediately when you save them
(typically to the target/classes).
--> Deploy on Save (will be referred as DoS) is supplementary feature that enables you to deploy your .class file changes to the server
immediately when you save them.
So currently you have few possibilities:
1) Turn on both (CoS and DoS) --> That means your changed .java files
will be compiled on save and redeployed to the server and also your
static resources (html, jsp etc.) will be copied to the server after
the save.
2) Turn DoS off but let CoS on --> in such case you will loose
everything related to "server refresh". Which means you should have
actual class files compiled in the target/classes but you won't see
any change in the browser
3) Turn both off --> NB let you to take care of build/deployment
--> It doesn't make semantic sense to have DoS activated while CoS is disabled which is why if you disable CoS, NetBeans automatically
disables also DoS
How should I configure that?
So the conclusion here is, you are not doing anything wrong and you
can't configure it that way.. NetBeans just don't support such
possibility yet. BUT the good thing is I'm currently starting to work
on issue 218345 which is exactly what you need. There will be a new
check box (already available in Ant Web project) named "Copy static
resources on save" that allows you to copy your html/jsp/jsf pages
while having DoS disabled.
I experienced exactly the same behavior. No problems with Ant but hot deployment with maven does not work properly. So far what you just wrote.
The answer was to switch to Eclipse >= 4. You can convert your NetBeans project in a console using maven:
mvn eclipse:eclipse
All you then need is an adapter for your app server e.g. for GlassFish. Try it, it's worth a try.

which is the best way to update an application from a server?

I'm looking for a non-webstart/jnlp solution.
I'd like to add to my app an update feature that checks in an ftp or http server and downloads the last version (if there is a newer one) replacing the libs that has been changed.
How can i do that? I want to implement something like JDownloaders updates.
Thanks
It looks like you just described exactly how to do it. Add an update feature that checks an FTP or HTTP server and downloads the latest version.
Remember that you cannot download and overwrite a file which is in use. So you have two options for a design from where I sit:
When you start up the application, copy all of the jar and library files to a /temp folder of some sort before running them. Then, when you download the update, overwrite the files in the original place. The next time the application starts up, it will use the new files.
When you start up the application, first startup an updater. Have it connect to the server and compare all of the file versions. It will be able to overwrite any of the application files because it doesn't use them. It only uses the updater jar. Once this is done and everything has been updated, then start a new process from the updater with the actual application. You will also need to put some code in to be able to update the updater jar. Either make the main application be able to update the updater, or use the first technique and run the updater from a copy of the updater jar.
Remember when you download the files that you should be downloading them to a temporary location and then moving them to the right place when they're done. This will make sure that you never leave your application in a "half-downloaded" state.
Beyond that, getting this to work is going to be about a lot of testing. Good luck!
Have a look at http://code.google.com/p/getdown/
According to this question on stackoverflow it seem to be a viable alternative for web start (at least worth having a look at).

Automatically update jar files

I am currently working on desktop software based on java.It's quite a big code base (more than 40 jar files).
I wish to provide an automatic update functionality. The desktop software constantly checks one back end system to see if there are new versions of the jar files available.
The problem now is: How to replace the updated jar files?
If you deploy your application using Java Webstart (JNLP), you get this mechanism almost for free...
From http://mindprod.com/jgloss/javawebstart.html
The key benefit for Java Web Start is automatic update without having to download the entire program every time.
Easiest would be to check for updates on each startup, download the updates and then launch your application. I think this is the way that Java Web Start works (see aioobes answer).
More complex would be to use either the netbeans or eclipse framework for your application. Both are rather complex and you will have to rewrite your application to work with them. This solution supports live updates.
As far as I am aware there is no easy way to update a running application. It is possible to load new versions of a class with a different classloader, but not possible to unload old versions while they are still referenced.
You can make a little server and a launcher which downloads the newest version, replaces the old one, and starts the jar with:
Runtime.getRuntime().exec("java yourjar -jar");
And you terminate the launcher with:
System.exit(1)
You can also serialize down your state (keep it in memory) and then create a new ClassLoader instance pointing to the new .jar files. Then serialize up your state again using this new classloader. You have just changed the underlaying .jars within a executing product.
Please note that you do not need to change the classloader for everything only for the part that is actually using the .jar files. This can be tricky to conclude what parts that are. And you might get nasty linking errors if done wrongly. So..
.. to keep it simple, use WebStart or a preloader that updates the .jars and then starts the main app (basically what WebStart does for you).
A reason for rolling your own, is that you can use your own format for the .jars, encryption, other packing formats etc.
After reading some answers to many auto-update questions, I thought of a solution. This is how I would implement a secure auto-update for a Java/Kotlin jar application.
Assumption: the installer will contain two jars: a launcher and the main application. Any shortcuts created will point to the launcher, but still be the name of the application. The release will contain the main application and the installer.
The launcher is launched first:
First check if an update has already been downloaded as app_name_update.jar
if an update has been downloaded, rename app_name_update.jar to app_name.jar
Start app_name.jar
This part does not have to be in the launcher, but it's preferred as to not slow down the main application: at this point, the launcher should check for an update (e.g. GitHub releases API) and download it to {CWD}/unverified_app_name_update.jar.
Compare the hash of unverified_app_name_update.jar to an online location containing hashes for all published versions. hashes.txt would be an example found in the same github repository. If the software is open-source, GPG signed commits is a must and the launcher should check if the latest update is a verified commit! If its a proprietary application, keep the hashes.txt at a separate URL from the release where your company does not control the infrastructure (e.g. GitHub).
Main app launched:
No need to check for updates unless updates are mandatory, in which case check for update -> if update found, start loading animation "updating" while you can detect that the launcher is still running. Ensure that the launcher has no race condition while loops!
I found ready project to solve automatically updating.
You can update your app, in your cases you can update jars and resources of your desktop app. The idea of the this is next: wrap you app with starter which can control updating and running you app. In details you can find here.

Categories