How do I attach java sources to project? - java

I am developing a WebSphere portlet in IDEA 11. The portlet is using some methods defined on portal. I don't have the production environment compiled classes or jars on my PC but I have the source code.
Can I somehow "attach" the .java files to my projects in order to build a war file that will be deployed into the production environment? Or do I have to build the production sources first (this seems to be harder since there are lots of dependencies)?

If this is just to test something while you await the JARs/compiled classes, you can likely do this by only bringing over the API (e.g., referenced interfaces that hopefully don't have external dependencies). Then, open up the compiled WAR and remove those .class files manually to avoid collisions with the real code on the server.
The biggest problem is that you will definitely run into issues trying to limit the exposure to the real code, unless the rest of the code was setup nicely to expose an API that has very limited dependencies.

Related

Test dependencies of Java web app library

I am coding a java web app.
When I started, every time I needed to use an external package, I would download the jars manually and download all dependencies of each jar manually and place them in the libraries folder (in Netbeans).
As time went on, I started using a dependency manager (Ant).
Now, I would like to use my dependency manager for all of my external libraries.
If, after executing this change I run my application and it successfully deploys (no ClassNotFoundExceptions and no NoClassDefFoundErrors), is it safe to assume that I have not missed anything and that my application will run smoothly as far as the external packages go?
Or, do I need to individually test out each functionality in my web app to confirm that the changes I made to the libraries didn't change how the application runs?
It's actually depends on the code inside these libraries. Only part of classes are loaded at startup, thus you can miss something. Also there might be a possibility that you're loading some classes in runtime manually, i.e. Class.forName(String) and this code has not been triggered at startup. Thus, I would say you can't be 100% sure.
Generally in Java here are 3 build approaches:
Imperative - you're saying "How to assembly your code". The typical example of this is Apache Ant.
Declarative - you're saying "Which code you want to assembly". The typical example of this is Apache Maven
Mixed - which takes benefits of previous systems. This is Gradle.
How it helps!

Redistribution of jars

I am currently compiling a list of third-party libraries used in a web application. The application is deployed in tomcat. I am wondering which of the third-party jars actually must or should be included in the distribution. In particular, I am currently wondering how to best use javax-libraries.
For instance, I would assume the javax.annotation-3.1.1.jar can be used in some standardized way, e.g., downloading it as an extension, without me including it into the distribution of my own piece of software. However, I have it included as a transitive dependency from jaxws-api which I need for web services and therefore it is included in the application's lib directory.
I understand I could use the Extension-List manifest entry to cause the target machine to download and install such jars. However, then they are visible for other applications on the same machine as well which may require other versions of the same libraries.
So, I have some questions about 3rd party libs and I would be very glad if someone could give me some hints:
What is the best practice to use third-party libraries?
Is there some best practice for the javax-libraries?
Can and should I avoid redistribution without imposing a large burden on the person installing the application?
I have to admit, I haven't understood the notion of "redistribution" here, maybe you're using some concrete application server terminology, so I'll try to provide a common answer here, assuming you have a war.
WAR (stands for Web Archive) should include all third-parties used by the application.
These reside in WEB-INF/lib folder.
Now, each Java EE server should "understand" javax libraries, because it contains the relevant interfaces. "javax" libraries usually provide interfaces and the implementation/code that works with these interfaces are provided by the application server developers.
For example for servlets technology, Tomcat (or name any web server) will contain HttpServlet abstract class inside its internal libs, it will scan your war and find where do you implement/extend it, this is how it recognizes your servlets actually.
Now, you shouldn't include servlet-api jar into your war, because its already exists in the application server.
If you're using build tools like maven, they allow to build your war so that some thirdparties will be used for compilation but won't be packed up into war.
I didn't understand why is it so difficult to install the application - in the easiest case - you throw the war into the web server and that's it.
Hope this helps

How to dynamically update (hot swap) jars in a web-app?

I have a webapp in a war archive which is deployed on cloudfoundry.
One of the libraries ("somelib.jar") used by the app is made by another developer.
I would like a way for him to upload several different versions of somelib.jar and test the behaviour of the app.
I have managed to get the jar uploaded to WEB-INF/lib directory of the deployment. I have also managed to unpack the jar into WEB-INF/classes. However, I have not managed to get the new version of the jar to be used. I tried various hacks such as those described in this question and this question without any luck.
Everytime, the classes/jars that get loaded the first time get used after that, even if we replace the actual .class or .jar file in the above directories.
Is there any easy way to achieve what I want?
Note: Since I dont have control of Tomcat (where it runs), I cannot configure Tomcat or make any changes to the server. I just have control on my war file, so everything needs to be done programmatically.
EDIT: the reason I want this is to reduce our testing time. Currently someone gives me a new version of somelib.jar, I repackage it into my application, upload to CF, send him a notification, then he tests the behavior of the new jar. What I would have preferred is that he upload his jar directly to CF and do the testing whenever he has a new version without the unnecessary intermediate delay.
In tomcat 7, you can version your WAR file and the new versions will gradually kick in.
http://www.tomcatexpert.com/blog/2011/05/31/parallel-deployment-tomcat-7
In order for you to control the application server yourself, you would need to deploy a standalone app into Cloud Foundry.
This blog should help you out with that:
http://blog.cloudfoundry.com/2012/05/11/running-standalone-web-applications-on-cloud-foundry/
This way you can custom configure your tomcat.
Everytime, the classes/jars that get loaded the first time get used after that, even if we replace the actual .class or .jar file in the above directories
That's the way that normal Tomcat (Java EE) classloading works. Your classes are loaded when first deployed, and any changes will be ignored (JSPs are managed slightly differently, but only in a development environment).
You should be able to solve this problem by using the Equinox OSGi bridge servlet. I haven't done this myself, but here's a writeup by a person that I respect.

Project with Guava, GWT and AppEngine

Is it possible to use the Guava libraries on a project done with both GWT and Google AppEngine?
I see that the individual jars (the standard Java one and the GWT compatible one) have the same package naming hierarchy. How do these integrate in a GWT+AppEngine projecT?
Yes it is possible. A few Guava classes won't be usable on AppEngine because of the restricted sandbox your app will run in, especially those in the .io package like Files (you will be able to read stuff but not write it).
Are you worried about deploying both jar files and having a conflict? If so, I think it will be fine - when you compile your GWT application, it turns into javascript, so you wouldn't necessarily be deploying the GWT compatible jar, just the normal one.
There won't be any conflict as the gwt one will be used by true DevMode client-side and the GWT compiler, the "normal " one will live in your WEB-INF/lib and be loaded (in DevMode) in a different classloader. It thus depends entirely on your project and build setup.
That being said I never tried it within the same Eclipse project. I always use distinct client and server projects, and -noserver in DevMode.

Java EE Jar file sharing

At our shop, we are maintaining roughly 20 Java EE web applications. Most of these applications are fairly CRUD-like in their architecture, with a few of them being pretty processor intensive calculation applications.
For the deployment of these applications we have been using Hudson set up to monitor our CVS repository. When we have a check-in, the projects are set to be compiled and deployed to our Tomcat 6.0 server (Solaris 10, sparc Dual-core 1.6 GHz processor, 2 GB RAM...not the beefiest machine by any stretch of the imagination...) and, if any unit-tests exist for the project, those are executed and the project is only deployed if the unit-tests pass. This works great.
Now, over time, I've noticed myself that a lot of the projects I create utilize the same .jar files over and over again (Hibernate, POI (Excel output), SQL Server JDBC driver, JSF, ICEFaces, business logic .jar files, etc.). Our practice has been to just keep a folder on our network drive stocked with all the default .jar files we have been using, and when a new project is started we copy this set of .jar files into the new project and go from there...and I feel so dirty every time this happens it has started to keep me up at night. I have been told by my co-workers that it is "extremely difficult" to set up a .jar repository on the tomcat server, which I don't buy for a second...I attribute it to pure laziness and, probably, no desire to learn the best practice. I could be wrong, however, I am just stating my feelings on the matter. This seems to bloat the size of our .war files that get deployed to the server as well.
From my understanding, Tomcat itself has a set of .jar files that are accessible to all applications deployed to it, so I would think we would be able to consolidate all of these duplicate .jar files in all our projects and move them onto the tomcat server. This would involve only updating one .jar file on the server if, for example, we need to update the ICEFaces .jar files to a new version.
Another part of me says that by including only one copy of the .jar files on the server, I might need to keep a copy of the server's lib directory in my development environment as well (i.e. include those .jar files in eclipse dependency).
My gut instinct tells me that I want to move those duplicated .jar files onto the server...will this work?
I think Maven and Ivy were born to help manage JAR dependencies. Maybe you'll find that those are helpful.
As far as the debate about duplicating the JARs in every project versus putting them in the server/lib, I think it hinges on one point: How likely is it that you'll want to upgrade every single application deployed on Tomcat at the same time? Can you ever envision a time where you might have N apps running on that server, and the (N+1)th app could want or require a newer version of a particular JAR?
If you don't mind keeping all the apps in synch, by all means have them use a common library base.
Personally, I think that disk space is cheap. My preference is to duplicate JARs for each app and put them in the WAR file. I like the partitioning. I'd like to see more of it when OSGi becomes more mainstream.
It works most of the time, but you can get into annoying situations where the jar that you have moved into tomcat is trying to make an instance of a class in one of your web application jars, leading to ClassNotFoundException s being thrown. I used to do this, but stopped because of these problems.
I really don't think putting libraries in common/lib is a good idea. The idea behind the use of war files as applications into a servlet container, is to have a real idea of isolation between your webapps. You could face errors like deploy some third party WAR (with it own libraries inside WEB-INF/lib) and it behave unexpectedly because it loaded other version of one of it libraries from the common one (remember that the regular behavior for load classes is first look at the common classloader and if you don't find the class look into the one for your webapp). Don't even mention how painful could be to move some application to other servlet container or an Application Server.
As mentioned before, you could use maven to deal with jar dependencies, and if you like the homogeneous use of libraries, define a POM parent (maven jargon) across all your applications.
In my experience you should be very careful with sharing libraries between web applications by moving them into the web container itself.
Let them live in WEB-INF/lib so your wars are self contained (you WILL be glad you did one day).
What you might consider is employing maven or Ant Ivy to pull in library jars from a common repository instead. This is very useful and should not be a problem in your scenario.
Edit: A notable exception is the Metro library - web service layer from Glassfish - which needs to be in the web container and not in the web application.

Categories