I have developed a web application which I am going to sell, but I face some security issues because I am going to provide a .war file to client machines and I found .war files can be easily extracted.
How can one provide security for war files to avoid being copied or extracted?
While searching I found Excelsior jet which converts web apps to native code but it's a trial version and I cannot afford its price so I want to know other alternatives.
A web app container cannot deploy an exe anyway. You can obfuscate your classes and maybe write a licensing module. If you prevent users from extracting your war you'll also prevent the container from deployment.
For example, you might use a Java Bytecode Obfuscater such as
yGuard
ProGuard
JODE
As for a licensing module, you may be able to use
this or this question.
The possible way is to
Use code obfuscator
Code in init() or somewhere check for license/access only one host.
Another option is to code your own classloader and implement it in modified web container
Related
So I'm developing a project for a client and in the end they will have a server running Apache Tomcat Server 7.0 and my project .war will be deployed there. Basically the .war will be running on their server and they will have access to it.
Can anyone provide any tips in how can i secure my code and prevent them to give it a look? Because the logic of the program itself it's what makes it valuable per se.
Thanks in advance.
There's no need to send source code up in a WAR file. But the resulting java binaries will still be subject to reverse engineering and decompilation, if they're so inclined. You'd need to look in to java obfuscation to try and manage that.
You can even use JSPs for presentation, but you'll want to pre-compile those in to servlets before distribution.
Do not disregard legal mechanisms through licensing of your work. Make sure your licenses and contracts are very clear about code ownership and rights to the software. That's a place for a lawyer.
If i want to deploy one application on different servers like Open Source Glassfish or TomEE. How can I achieve that without having to include different libraries for each application server? As an example if would like to use Jersey as the rest framework and eclipselink as the persistence framework i have to make sure both support these frameworks. But in case of TomEE it's shipped with other implementations like OpenJPA.
Is it possible to ship the dependencies only with the project and not in combination of server libraries + project libraries?
What is a good way to achieve server compatibility?
Any information or link which describes a solution or help me understand why it's done this way would be great.
Thanks in advance
This is more of a application server classloading issue and usually all application servers have a provision for a configuration file which you can put in your application and instruct the server to load the libraries included in the web application instead of the one present in application server. For e.g., Weblogic has a weblogic.xml file which is put in WEB-INF of war application and where you can instruct server to prefer the application packaged libraries. For JBoss there is similar configuration file jboss-deployment-structure.xml. This way it is easier to have a self contained application which contains all dependencies even if the server has equivalent libraries. Also you can upgrade to higher version of libraries than supported by application server otherwise you have to resort to all sort of hacks.
Easy solution I can think of is using ant task to create war file for each servers. You can have at most 2-3 servers in reality like tomcat ee, jboss and glasfish. So create 3 ant tasks for each like tomcatWar, jbossWar and glassfishWar and each ant task makes sure required jars are shipped as well in the war. This is more easy and extendable solution, also easy to understand and modify for new requirements.
I have a Java application (a quite large one with many external .jar dependencies as well as dependencies on images) and I need to package it up so that someone can double click to run, for example. Or something easy like that.
It uses Java Persistence, so it requires a sql connection which is specified in the Persistence.xml file in the Java Project.
How can I package this up? I was thinking:
the installation process should validate that the user has MySQL installed and if not, direct them to install it
the installation process could ask the user to enter credentials for any database and then I could update the Persistence.xml at run time
These were two ideas I had...but I wasn't sure if there was a known solution to this problem. Any help would be much appreciated!
I think you should take a look at embedded database solutions, like H2. Also, you can package your application using maven's shadowing or jar plugin, having the jar-with-dependencies profile activated.
This will nicely rid you of checking for database servers running on the client machine, and also will give you the proper means of bundling the application in one nice JAR, albeit a little large.
Maven is a build ecosystem and toolset especially designed for building Java applications and executing the code -- and generally doing whatever else you can imagine that's possible to do with and to your code.
It has a rich API for developing plugins and many developers have exploited this feature. There are numerous plugins for building -- and launching -- and packaging your application as well as helping you manage your applications dependencies.
Maven's shadowing comes in the form of maven-shade-plugin, available here. What it does is that it helps you create a single JAR file from all your dependencies. Also, there is the maven-jar-plugin which offers a profile jar-with-dependencies. It is also accessible from here.
H2, on the other hand is a full-fledged RDBMS. This is the website: http://www.h2database.com/html/main.html, and here is a tutorial.
You can find information on embedding the database here:
How to embed H2 database into jar file delivered to the client?
Embedding the Java h2 database programmatically
h2 (embedded mode ) database files problem
I would also suggest you use a combination of H2/Hibernate/Spring which is a very easy setup and provides you with really rich features and an easy-to-use API.
I hope this helps you :)
Building a sophisticated installer that checks lots of dependencies, and runs on lots of different platforms (which I assume you want) is complicated.
I suggest that you look at an installer generator; see What is the best installation tool for java?
Another alternative that I've seen in a few products is to write a (non-GUI) installer or configurer in a scripting language like Perl.
I wrote an installer using ANT, but has no GUI. Also, I used Iz Pack (good option), so I think that depends on how smart do you want it to be, if you are supposed to use it, or a non-technical person, etc.
I have a lot of small-ish Java command-line apps that have to use a vendor set of jars to make their connection to the servers, and while writing these apps has been pretty easy, maintaining them is turning out not to be.
I built them using Maven and some templates that gave me a pretty quick turnaround on development time, but these are all standalone command-line apps so far.
The pain comes from the updates to the vendor servers. Whenever it happens, it forces me to recompile all of these applications with the new jars in play, otherwise I'd get SerialVersionUID Exceptions and borked apps.
What I'm considering
I was thinking that it would be possible to use Maven to generate the app and then throw it in an app server with the server providing a set of shared vendor .jars in whatever /shared classpath it provides. That way I could just update the .jars, restart the server, and everything will likely continue without error.
However, I'm not sure what is required to get that working. They aren't .war's, and most of these apps use other .jars besides my code that isn't usually shared.
Questions
What kinds of deployments work like this?
Are there other ways to do this that I'm missing?
Any tutorials, frameworks, etc., that would make this simpler?
I could just share from my experience. We have 3 ways of overcoming this at the moment. The first way, was our old way, which we still use.
Create a base project which we link to with all our external JARs. The user project when compiled/deployed checks for a newer tag of the base project than it is currently using, and if there's a newer tag, it will fail and force the user to check for the updates and recompile. The benefit of this is that at compile time you can check for new jars, and we get a list of what changed, and reload the jars. In our IDE we can quickly see if anything changed from the API - it has been known to happen, then we can fix and recompile. Also because we're aware of the changes, we can read the changelogs and see if any of the changes affect us, and we then retest parts of the application that depend on these libraries.
We use Maven, but instead of the public repositories, we maintain our own repository, where we only move a library into our local repo after it has been tested - so no surprises for us.
This method is unique to a Tomcat deployment, but we also load libraries via the Context using a classloader. It's not my favorite way to load external jars, but this one works without a deploy. Of course since the compiler isn't there to help you, the new jar can not be 100% compatible with your code, and you can end up with some runtime NoSuchMethodError or ClassNotFoundException expections.
I might be misunderstanding your situation, but if the interface you use in the vendor libraries does not change between versions, couldn't you just keep the jar-files in the classpath of your command-line applications and thereby just overwrite the vendor files when necessary? In that way you would only need to recompile when the interfaces change in a way to break your code?
I am wondering if it is possible to have a Java desktop application, on startup, look to some URL, to see if it needs an update, and if so download necessary JAR files, and add them to classpath for the running program.
If the old jars are there, they shouldn't have been loaded into the classloader yet, at this point should they? Is it possible to swap them out before they are loaded w/out restarting the application?
JNLP (Java Web Start) will do all of that for you.
It should be possible. The URLClassLoader is a place to start.
It's possible but prone to error.
A somewhat cleaner approach is to have a "launcher" application which does not rely on any of the updatable JARs do the above and then launch the actual app.
You may want to check out this question for more details on this topic.
Java Web Start is probably your best bet. The required jar files should be identified in the descriptor allowing your to manage the version control.
If you have a dynamic application that needs to discover and download classes dynamically at runtime, then you could look at Dynamic code downloading using RMI.
Java Web Start is a good choice but has some quirks. Notably:
Code which is updated must be downloaded before the program starts. A more modern approach would download updates and apply them at next start.
Default is inside a sandbox. If you need to go outside of that you must sign your code, which is rather cumbersome until you automate the deployment process (or use Netbeans which helps quite a bit).
Problems are not easy to debug - only tool is enabling full trace in the Java Console.
Caching of jars in the client is error prone. When you update, be sure that the URL is unique for each deployment component so the cache will not be used.
But WHEN it works it works pretty well. It is to my knowledge the easiest way to have a centralized version easily updateable of a given Java application.
--
EDIT: It appears that the "start program and transparently download updates if available" functionality is present in the latest Java 6. I have not tried it yet, but will soon.