Reputation: 21
I have a maven web app, using WAS 8.5.5.
On app startup I'm getting the following error:
Caused by: java.lang.NoSuchFieldError: org/apache/http/message/BasicLineFormatter.INSTANCE
This means there's some sort of mismatch of jars (httpclient & httpcore) in my classpath.
To get more info, I ran the following code:
ClassLoader classLoader = Test.class.getClassLoader();
URL resource = classLoader.getResource("org/apache/http/message/BasicLineFormatter.class");
log.info("Outputting resoure info: " + resource.getFile() + " " + resource.getPath() + " " + resource.getRef());
try {
log.info(FileLocator.resolve(resource));
log.info(FileLocator.toFileURL(resource));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This gave me the following output:
start Outputting resoure info: /org/apache/http/message/BasicLineFormatter.class /org/apache/http/message/BasicLineFormatter.class null start jar:file:/C:/RAD9.0/IBM/WebSphere/AppServer_2/plugins/com.ibm.ws.prereq.jaxrs.jar!/org/apache/http/message/BasicLineFormatter.class start file:/C:/RAD9.0/IBM/WebSphere/AppServer_2/profiles/AppSrv01/servers/server1/configuration/org.eclipse.osgi/bundles/105/1/.cp/org/apache/http/message/BasicLineFormatter.class
These are both obviously loaded to WAS on startup. How do I stop this from happening? I tried changing the priority of the module loading in the app settings by setting load parent last, but that stopped the app from coming up at all.
Any ideas?
Upvotes: 2
Views: 3441
Reputation: 4245
You can also see where the offending class is loaded from using the Class Loader Viewer and searching for it. You have to enable this first by clicking Servers > Server Types > WebSphere application servers > server_name > Class loader viewer service, enable the service and restart the server.
As a quick fix, without having to switch to PARENT_LAST and create a shared library, I copied the JAR file from my .m2/repo folder to the AppServ/lib directory.
> cp C:\path\to\your\.m2\repository\org\apache\httpcomponents\httpcore\4.3.3\httpcore-4.3.3.jar "C:\Program Files (x86)\IBM\WebSphere\AppServer\lib"
Then I added an entry to the JVM classpath within the server console:
Open https://localhost:9043/ibm/console and go to:
Servers > Server Types > WebSphere application servers > server_name. Then, in the Server Infrastructure section, click Java and process management > Process definition > Java virtual machine
Then enter the following under "Classpath"
C:\Program Files (x86)\IBM\WebSphere\AppServer/lib/httpcore-4.3.3.jar
Use a semicolon to separate entries.
Restart to retest.
Upvotes: 3
Reputation: 3176
It looks like you have a library in your application at a newer version than a copy in the application server so you end up with a mix of classes visible to your application. As you notice this is a bad thing.
There are a few ways to get around this, but the simplest is to change the classloader order to load classes from your application before the runtime. You can do this in the admin console by navigating to the application, selecting classloading and choosing the radio button labeled Classes loaded with local class loader first (parent last).
If you do this though you should make sure you don't include the Java EE packages in your application though (that sometimes happens with maven built applications).
Upvotes: 2