How to check the class conflict between the application server and WebSphere? - java

I want to know whether any mechanisms /tools to check the same class conflicts between the jar files in my application server and Websphere.
I have some of jar in /WEB_INF/lib, class files in /WEB_INF/classes
and also in ${WAS_INSTALL_ROOT}/plugins. So how can I check whether the jar contain same classes ? Any tools available ? Any suggestions ?

Assuming you're asking about traditional WebSphere (rather than Liberty), it sounds like you'd benefit from the Class loader viewer tool.
This can be helpful when unsure if you're loading a given class from some part of your application or some part of the runtime. (I'm guessing when you ask about conflict between "the application server and WebSphere" you might mean conflict between "the application and WebSphere".)
This tool is documented here and illustrated with some examples in sections 20.3, 20.4 in this redbook.

There is a tool that does precisely what you want - the migration binary scanner was updated to perform an "inventory" report that will check for duplicate classes within your app and potential conflicts with WebSphere libraries. For more information, see this article: https://developer.ibm.com/wasdev/blog/2017/01/25/binary-scanner-not-just-migrations-anymore/

Related

Find all provided jars in Websphere

I'm using the Websphere Application Server 8.5.5.6 and 8.5.5.8 and from time to time run into problems when some jar or the other in my application conflicts with one that is already present on the WAS. It's easy to fix of course, simply mark the dependency as "provided" in maven and there you go, but since IBM seemingly choose to write the AS with the most obscure error messages possible it takes ages to find something like that out.
My question which google hasn't been able to answer so far:
Is there a complete list somewhere which libraries in which versions are provided with Websphere?
Assuming you're referring primarily to Open Source packages, the official list is here: https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/opensourcesoftwareapis.html
Beyond that, most of the stuff visible to apps should be Java EE/SE APIs, which I assume you were already expecting, and IBM-specific implementations (things in com.ibm.* packages), which are hopefully at low risk of collision.
At least if you are on Windows: take Process Monitor (not Process Explorer), and fire it up filtering on Path contains .jar. Then start WebSphere. At some point it will starting loading jars from various directories. Process Monitor will show you which are those jars, and where they are being loaded from.
This should provide you with first hand information without reading IBM documents.
Besides, probably you are aware of that, but in any case: you should be careful with marking a dependency as "provided", since the version of the library used by your application might differ from the version used by WebSphere.

How can I include a jar file in a distinct package when deploying

I have an ant script that I use to build my J2EE application and create jar files. The problem is the following: Two jar files are necessary for the application to run.
commons-math-2.0.jar
commons-math-1.0.jar
However, I want to only use the 2.0 for a particular package inside the application with the rest of the application using 1.0. How can I build the application to only use the 2.0 version for example with a package name such as com.naurus.eventhandler.risk? Again, I'm using an Ant script, but if there's an easier way to do this sort of thing I'm willing to experiment. Thanks!
If the two jars contain different classes/packages there should be no problem to have all of them in the application classpath. It is then a matter of discipline not to use the classes from the one jar in the other package.
However I guess these two jars contain mostly the same classes/methods? There are many ways of using different versions of the same classes:
Using different ClassLoader instances. I would not qualify it as "easy", far from it means opening the door to a bunch of nasty bugs. (can be helped using a tool like OSGi)
Splitting the application in two processes, these process being launched in the same Ant target and using any mean (CORBA, RMI, REST, etc.) to communicate.
I would not advise using any of these methods though. It would probably be simpler to make all your packages use the same version. Is there any specific difficulty in doing so?
That will be problematic since both JAR files will end up in the same classpath when you deploy your J2EE application. You could achieve what you are trying to attempt with OSGI bundles, which allow each package to have separate dependencies. However, that is a relatively large refactoring of your application.
IMO, it would be best to either:
a) Duplicate the features you need from 2.0 (if the number is small and the license allows it, e.g., package individual classes).
or
b) Spend the time to upgrade the entire application to 2.0
You could use the manisfest in your jar to define the classpath.
http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html
Although honestly it seems a bit convoluted, but it is your requirement.

Adding Common class for different blackberry application

I have written a common class which I want to use in separate Blackberry applications. This class is not in a separate project but just at a common location and I have linked the path of the common class in Java Build Path. I have added same common path to both of my BB applications and they builds and installs without any problem. When I run one application, it start running but when I run the other application, it gives error message "class xxx multiply defined" error and exits.
Any idea what is going wrong here. Thanks in advance
Regards,
Braj
BlackBerry doesn't work as other Java platforms. In BB Java, you can't have two classes with the same full qualified name, even if they live in different projects.
You'll have to rename one of them (either change the class name or the package name) for it to work.
In fact, the only platform where I have seen this restriction is BB. It is a real pain in the ass since you can't reuse a jar library in different projects without renaming it.
UPDATE:
This is the official article on the topic:
http://supportforums.blackberry.com/t5/Java-Development/Application-throws-quot-multiply-defined-quot-error-at-start-up/ta-p/501498
All applications in RIM OS run under one instance of Java Virtual Machine. And therefore it is allowed only one class with particular full qualified name. Adding another class with the same name will lead to failure upon running both of these classes.
There is a library thing, supported in RIM OS, but I do not recommend to use libraries in your project, unless it is very necessary.
It is because if you have several apps with the same library, but with different versions of libraries you may get the same error you reported in your question. And it is hard to manage libraries when you have many applications which use these libraries.
I recommend to copy source code of your library to the project you are working on. Copy via refactoring, to change all full qualified names of classes included in that library.
Thanks guys for replying. I have created a common library and put common code in that. Now I can use this library in different applications without any problem.
However, when I install my applications using BB desktop Manager, the library appears as part of first application but not in second application. I assume it is because, second application realizes that the library is already been included so doesn't need to include it again.

Is there something like the Weblogic filtering classloader for Websphere

I'd like to use something like the Filtering Classloader to prevent specific packages from creeping into the application context and becoming visible to Spring.
Changing the classloader order causes all sorts of nasty problems so I´d like to try this route.
Is it possible to achieve this with Websphere 6? If not, can I replace my own application classolader and implement the filter myself?
There is no such filtering mechanism in WebSphere, and there is no way to replace the application class loader. You'll have to use PARENT_LAST to override classes, sorry.
bkail's answer is right, WAS doesn't have such feature even in its latest public version (8.5.5).
I just created a RFE requesting such feature so whoever is interested in this, please vote for it which may increase the possibility of this being implemented:
http://www.ibm.com/developerworks/rfe/execute?use_case=viewRfe&CR_ID=43936
(IBM ID required)
In the meantime, you may use isolated shared libraries to override any particular classes (the above mentioned class loading order control - like parent_last - is too rough as it affects the class loading order of the whole application or module)
Create a shared library with desired jars on the classpath, configure it as isolated shared library, reference it from the deployed application (or module).
See here for complete documentation
http://pic.dhe.ibm.com/infocenter/wasinfo/v8r5/topic/com.ibm.websphere.base.doc/ae/tcws_sharedlib.html
I was just about to post the same question. But the answer was quite unsatisfying. I however checked the request from Petr H at the IBM developerworks and IBM did implement this feature (Huge thanks Petr!):
"WebSphere Application Server V8.5.5.7 (=Fixpack 7) gained the ability to prevent packages from the server classloader being visible to applications. This was delivered in the document "ISOLATE DEPLOYED ARTIFACTS FROM OSS PACKAGES" and is documented in 'Isolating open source software packages'.
The supplied links describe the mechanism by configuring always-protected packages. You basically have to do the following:
Under Server Infrastructure on the server settings page in the administrative console, click Java and process management > Process definition.
Select Java virtual machine.
Define the following system properties in the JVM generic arguments section as follows:
-Dcom.ibm.ws.classloader.server.alwaysProtectedPackages=org.bouncycastle.
Please not that the final dot "." is really important otherwise everything will be ignored! Several packages can be added by comma ","
Click Apply, OK and save the changes. Make sure that a file synchronization is done before you restart the servers. Restart WebSphere Application Server for the changes to take effect.
Examine the native_stdout.log and find the system properties that are previously defined. For example, when you specify always-protected package org.bouncycastle., statements such as the following might appear:
ProtectionMetaData.clinit: system property: com.ibm.ws.classloader.server.alwaysProtectedPackages=org.bouncycastle.

EJB Dependency Version Conflict in Sun Application Server

To summarize the issue I'm encountering, I have an EJB which uses version A of a library (let's call it dep-vA.jar). dep-vA.jar is packaged in the root of the EJB's jar file. The domain lib folder in the application server contains version B of the same library (let's call it dep-vB.jar). When calling the EJB, I get an error due to dep-vB.jar file being loaded rather than dep-vA.jar.
I guess the first part of this question is, does Sun One Application Server v9.1 isolate EJBs from each other? I was under the impression that it does. But it seems like another application loaded dep-vB.jar and this EJB is directly using it without loading its own.
The second question is, if the app server does isolate EJBs, does it load dependencies from the EJB's jar file before looking in the application server's lib folders? I was under the impression that this is also true, but maybe not...
Is anyone familiar enough with Sun application servers to explain why dep-vB.jar is being loaded rather than dep-vA.jar? Is there any way to get it to load dep-vA.jar without changing what's in the application server's lib folders? (I would hesitate to do anything that might affect other applications on the server)
Thanks.
I guess the first part of this question is, does Sun One Application Server v9.1 isolate EJBs from each other? I was under the impression that it does. But it seems like another application loaded dep-vB.jar and this EJB is directly using it without loading its own.
According to Sahoo (which is a GlassFish developer), the Java EE spec does not mandate class loading isolation among modules of a single ear so the behavior can be different from one app server to another. With Sun ONE, my understanding of the documentation is that EJB-JARs are isolated.
The second question is, if the app server does isolate EJBs, does it load dependencies from the EJB's jar file before looking in the application server's lib folders? I was under the impression that this is also true, but maybe not...
It's a parent-first strategy (and to my knowledge, Sun ONE allows to change the delegating mode for webapps only).
That being said, what happens if you list dep-vA.jar in the Class-Path entry of the MANIFEST.MF of the EJB-JAR?
See also
Chapter 2 Class Loaders of the Sun Java System Application Server Platform Edition 9 Developer's Guide
Packaging EJB 3 Applications
I haven't used that particular server, but I do know that in WebSphere, there is an option to use PARENT_FIRST or PARENT_LAST classloading. You would be looking for an equivalent of PARENT_LAST where the classes are loaded from the EAR first before going up to the server.
I would assume that such a configuration is possible in any app server, as you should always be able to enforce your application specific jars to be loaded over any others.

Categories