I am just wondering, if the below is possible with Websphere or not?
I have an Enterprise application using Websphere 7 and with PARENT_LAST classloading mode. I am now trying to use a third party feature namely, gemfire in the application. My application with gemfire runs perfectly in PARENT_FIRST classloading mode. But, I can see some linkage errors occuring because of PARENT_LAST setting. Temperarly, I could solve them by removing the classes that are conflicting from gemfire jar(By this, I am actually asking those removed classes to be loaded from web app server). But, I am not sure if this will create some bigger issues as my appliaction grow to its fullest.
My question is : Suppose we have abc.jar in both web app server and also in gemfire.jar, with PARENT_LAST loading mode.Is it possible to solve the above class conflicts by not removing any class files from jars, instead tell the classloading mechanism to use the class loaded from web app server at a particular case and use the same class loaded from gemfire jar(meaning load from application) at another case?
Thanks
Yes, it is possible. We are using a similar setup. You should be very careful though and only use the exact same jars (or at least the same classes) in all the places you need to have them.
Related
I have a web application that used to run fine on many web servers (tomcat, jboss, weblogic and websphere). Now, however, it has an error when deploying on WebSphere 9.
The app contains the jar javax.transaction-api-1.2. Some of its classes, e.g., javax.transaction.xa.XAResource, are also included in Java SE, but not all of them. Some are specific to Java EE and are required by some 3rd-party libraries in my app. The app is always deploying with child-first (parent-last) classloader.
WebSphere 9 throws this error during startup when the app tries to load the Oracle JDBC driver:
java.lang.LinkageError: loading constraint violation: loader "com/ibm/ws/classloader/CompoundClassLoader#7157be44" previously initiated loading for a different type with name
"javax/transaction/xa/XAResource" defined by loader "com/ibm/oti/vm/BootstrapClassLoader#422c7b1b"
Note that we aren't actually using XA transactions in the app, we are using regular transactions.
On other servers, and previous versions of WebSphere, it was never a problem. The server didn't care that we load XAResource from inside the war, even if it was previously loaded somewhere in the server. Now WebSphere 9 is different, it says that the app classloader already loaded this class from the server, but I don't know why or when did this happen.
Any idea how to solve this?
Remove the transaction API from your application. JTA 1.2 is already included in the server and provides no value in your applications. It's always risky to bring Java EE/SE APIs in a parent-last class loader unless you are 100% certain that they are technically necessary, because they can lead to issues like this one.
I can't say how this worked in previous server versions (there have been some Java-level changes in enforcing linkage issues like this), but the solution is reasonably straightforward.
At the end we did two things to solve this problem.
1) We upgraded the jta jar to version 1.3 (link here). This jar solves the problem by avoiding duplicate classes - it contains only J2EE classes and omits the J2SE classes that are already included in the JVM.
2) We upgraded WebSphere server from 9.0.0.7 to 9.0.0.11.
At the time, I suspected just upgrading the jar should suffice, but our QA had some issues with it and they also upgraded the server. Due to lack of time, we didn't investigate it further and just decided to do both.
Does parent_last affect other applications ?
Is my application using parent_last affected by other applications?
The server is set to "Multiple Classloaders" (one for each application IIUC).
In my understanding, this would mean that all classes are loaded from the application, correct?
What happens if another application loads a class present in websphere extensions, and lateron my application uses that class. Will it be reloaded, or will the one from parent be used? (it might be incompatible to the classes in my application).
The websphere manual says:
"By specifying Classes loaded with local class loader first (parent last), your application can override classes contained in the parent class loader, but this action can potentially result in ClassCastException or LinkageErrors if you have mixed use of overridden classes and non-overridden classes."
But I do not understand this potential risk. Can somone please provide examples for this?
Classes loaded by application class loader cannot interfere in any way with those loaded by other applications since application classloaders are isolated from each other.
The quote that you provided warns about potential problems that might occur when libraries have transitive dependencies. For example, your application uses libraryA that depends on libraryB. LibraryA is some sort of "standard" library provided by application server, so you don't package it with the application. Then, if for some reason you need to have libraryB in the application and the version of it is different from the one expected by libraryA, you might have problems with incompatibility.
Is there a way to make the Websphere Application Server use the jar places inside the application's WEB-INF/libs folder and ignore the one that available within the server's plugin folder.
I am using EMF in my application and the version provided in the server doesn't include support for EMF GenericType, so I want to make the application use the jar file inside the libs folder.
Thanks for any help
This is quite possible. You need to change the classloading order from parent first to parent last. This will cause it to consult the server runtimes version of the code after your application. This is documented in the infocenter.
Another approach you might want to consider is to use an isolated shared library. There is a good introduction for those in IBM Education Assistant. These are more complex to setup, but using parent last classloading order can sometimes cause unexpected side effects that don't occur with isolated shared libraries.
The current system I am working on uses Tomcat 7.0 and Spring 3.1 the system is a collection of web apps that all have the same classpath in WEB-INF\lib, I am thinking of adding spring 3.1 to my tomcat\lib so that all the web apps have access to it. Is this safe to do with Spring 3.1?
Safe to add Spring 3.1 to the Tomcat main lib directory? Quite possibly. Good idea? Probably not; as the system administrator you'd be taking on the responsibility for ensuring that all the webapps can use that exact version of Spring (including all the issues that can crop up when you update things) because the webapps would not be able to override it to anything else. (To be fair, they could load classes from elsewhere that weren't in the standard system version you're proposing, but that's likely to be an extremely bad idea as there would be problems with warring versions of the same library. That's a very confusing situation to be in; avoid if at all possible!)
As a general rule I only put very basic shared libraries like JDBC drivers in tomcat/lib. Sharing other libraries will often lead to classloader issues in tomcat. Unfortunately, I don't know the publish date of it, but you might find this article http://www.mulesoft.com/tomcat-classpath useful.
We are using WebSphere 6.1 application server with default classloader delegation mode i.e. PARENT-FIRST. We think about changing it to PARENT-LAST to be able to choose our jsf implementation or our webservices stack.
As PARENT-FIRST is the default I wonder how many people switched to PARENT-LAST, and what was the reason to switch, and if your life became better since you switched :)
We have a lot of applications in production so I cannot just switch to see what happens, if we do it we will have a lot of testing so I’d like to have to some feedback if you have switched to PARENT-LAST.
Thanks
On projects that I'm assigned to, we actually do switching to PARENT-LAST for most of our applications. The reason for that is usually an app-specific implementation of something, or a need for app-specific property bundle that Websphere uses too (overriding the Websphere setup of commons-logging, for example).
If something breaks after the switch, it is usually because of somewhat wrong setup of the application that suddently starts to be used (while before the switch it was overriden by Websphere's resources).
Portlet applications (deployed on WebSphere Portal Server) always switch their configuration to parent last. In my experience it is always better to switch to parent last, especially if you are using commons logging. This is because WebSphere includes a truck load of stuff in its own classloaders which are often a different versions/configurations to the one that you want to use.
If you are doing it, I would recommend that you script up the deployment of the application because it can be one of those things that are missed when you do a deployment.