In the process of developing applications, it is common, that you use prefabricated functionality or components. Such used functionality is often packed into library that consists of set of JAR files, ready to be included into your applications classpath. Such library could be:
- logic written for previous similar task
- integral part of the project, common to many modules(applications)
- framework that you want to re-use and is not delivered with the engine of your choice.
In order to use it you need a way to plug that library into AS Java and add its classes to your applications classloader.
A very straightforward way to achieve this goal is to copy the JARs into lib folder of the application server and add them to its classpath. This way the library is indispensable part of the application server and you get the classes for free out of the parent classloader. Although this works with most application servers, few problems pop-up:
- You need to touch servers config files just to include a library
- In order to update the library, you need to restart the whole server and eventually fix its classpath (if new version is structured in different way)
- What if your neighbour needs the same library, but different version?
- How about maintaining your cluster up-to-date every time a library is updated?
- Your install script has to fiddle with the servers classpath
- What if this server instance runs hundreds of applications like yours that use different library each?
I think the last bullet is the most frightening one. How about hundreds of applications, using dozens of libraries? Guarantee for disaster and ill-tempered sysadmins.
As we have had that problem with earlier releases, we have come to a solution online libraries. Some of you may know them, some not. Either way, now we have a better solution for this problem. You don’t need to touch engine’s classpath and you don’t have to worry about copying the jars. All can be done easily in the same way you develop application; what is even better – you distribute these libraries via the same channel you use to deliver applications. Ask the engineer in charge who has to worry about your production and test servers, if you wonder how important this is.
If you are interested how this solution was further refined in our JAVA EE 5 Edition server, check the rest of this post.
Lets imagine we have three solutions, implemented as set of applications . These solutions are using some common shared library. For simplicity, I will focus on one of these applications, which presumably is web application, having a JSP page consuming this common functionality. Once you know how to do it with one application, you have the knowledge to setup larger sets of components.
I will cover two usecases for library origination: in-house developed (in-house packed) and 3rd party library, already packed.
Warning : this does not cover cases where you want to exchange already provided library such as the XML parser.
How it works
In order to achieve our goal, we need a way to package the library so you can deploy it on AS Java in the standard way. Once deployed, we need a way to consume it by the application. This is achieved by using application runtime reference and application service.
Runtime references are a mechanism to couple applications and specify that application X needs application Y in order to run & function. Please check this article for more details. It is in the 6.40 section, however there arent serious changes in the handling of the dependencies.
Application service is fresh new application programming model. I wont go into details here. What is important to us in that case is the fact, that it handles JARs as fullblown modules just like any other EJB, Web or other Java EE standard module. You can bundle library module as part of your application and have the JARs accessible as usual; you could bundle it as single module in the application and have the JARs shared that way. This is exactly what we will do.
One additional feature of application services are the start-up and shutdown classes. I will go into details about this in another post.
I will show you how to build the application containing your in-house or 3rd-party JARs and an example consuming application. Open your NetWeaver Developer Studio (remember, I am using JEE 5 edition of our Java Application Server) and let’s roll.
Bundle the library
You need to create an application project, that will pack the jars and produce EAR. It is the wrapper project, that contains application description and information about the other projects, delivering the modules. We will also setup second project, that is delivering the application service module (the jars)
First – the library project (providing the jars for the module). Lets see how in-house sources are bundled :
Create simple Java project.
Put your shared logic inside. My logic is pretty simple, as our primary goal is the packaging and coupling.
Next – the application project (remember, the one that produces the EAR):
Please note the choice, Enterprise Application Project 5 will not do the job. You have to go exactly for the wizard shown above.
Here, you need to check the Library Container facet in order to get the needed descriptor.
Finally, add a module to the EAR – the Java project containing our logic.
With this you are ready and have created all needed to code your common logic and produce deployable afterwards. As I expect that you will be using our engine, you need to produce SDA that can be fed into our delivery logic (explained below). If you want to use your library on another engine – just get the jar produced by myUtil project and deploy it accordingly.
I know some of you are interested in bundling ready JARs. Please read on, as the steps are exactly the same, at the bottom you will see what is the only difference.
Create the client application
As I know you can put together JEE 5 web application, I will jump directly to the specifics.
You need a JSP that is consuming the shared logic. Here is the source I came up with :
Now you need to instruct the engine, that your application needs to access class(or logic) located in another component. In our case we will put application-application reference. For this purpose, navigate to META-INF in your JEE application project and open the application-j2ee-engine.xml file. One of the portions of this file describes application references I mentioned in the beginning. Here is how my descriptor looks after adding manually the reference (sorry, you have to edit the XML) :
We are finally ready to build, deploy and test. If you are curious you could first deploy both your web application and library application (libraryApp) and test if the JSP works without putting the reference. On my engine it did not work 😉
With the Developer Studio coming on the CD with our JEE 5 engine edition, it is easy to deploy your project. Just right-click on the web application project and it builds & deploys for you (for more details, please consult the manual) :
Of course, you should not forget to deploy both libraryApp and the client application!
Yes, its working…
Adding prefabricated JARs
Now as promised, I will go couple of steps back and give you hint how to have the same setup, this time with prefabricated jars. You need only the application project (libraryApp) this time as the jar files are already fabrciated. Go to the properties dialog and navigate to J2EE Module Dependencies as shown below. There using Add External JARs button add all the JARs you need.
With the exception of this detail, everything else is the same. Use the Export feature in project’s context menu to verify that your libraryApp.ear contains all desired resources.
I hope this was useful to all of you.