Well, I replaced all those JARs and it didn't seem to help any. The httpclient class files are also contained in a few of the other JARs in JBoss, and replacing it everywhere is not completely easy. Hmm, there must be some way to tell JBoss to use my JAR instead of the built-in JARs.
Now I am completely baffled. I took apart jbossall-client.jar and replaced the httpclient in there. I checked every jar in the jboss directory for httpclient, and replaced every instance of it. I deleted the tmp work directory with my app. And I still get java.lang.RuntimeException: java.lang.NoSuchMethodError: org.apache.commons.httpclient.methods.PostMethod.setRequestEntity(Lorg/apache/commons/httpclient/methods/RequestEntity;)V
which seems impossible because every PostMethod that I can find within the JBoss directories at this point inherits from EntityEnclosingMethod, which certainly has setRequestEntity. It's almost like JBoss is loading this particular class from somewhere outside the JBoss directories. Does anyone have any ideas? This is a bit crazy. It shouldn't be so hard to get httpclient working within JBoss.
I had it print out the classloader in question, and got:
No idea what to make of this, because I can't find ANY place that it could be loading this old version from. I have looked in every jar in the JBoss directory. Does JBoss ever load classes over the net, or from remote sources? Is there any way to make this UnifiedClassLoader just tell me which jar file it's looking at?
Now I tried setenv doing:
setenv JAVA_OPTS '-Xbootclasspath/p:/home/me/MyApp/extras/httpclient.jar'
before running JBoss and it still did not work. I could modify Sun's classloader in rt.jar so that it is forced to load all classes from the httpclient from a certain directory, or I could rebuild httpclient and change the package name so that it will be a totally different class... but this seems like a crazy amount of stuff to do to use a class, especially when the class I am trying to replace is no longer within the jboss directories at all. Can anyone confirm where JBoss might be trying to load that class from? Does JBoss ever load classes over the net when it starts up? Or does it ever use some other strange classloader formats, like loading from non-standard class files?
Can you set Java2ParentDelegation to false on your loader-repository (jboss-app.xml) and see if that lets you see your local classes first?
<loader-repository> seam.jboss.org:loader=seam-pay <loader-repository-config>java2ParentDelegation=false</loader-repository-config> </loader-repository>
Ha! Thank you. That worked.
I was also noticing that when I ran my XML binding stuff from the command line, the output was different from when I ran it in JBoss. The reason for this was that JBoss ships with its own jaxb jars, which were conflicting with Java 6's built-in jars. I just deleted the JBoss jaxb jars and that worked correctly too.
My suggestion for JBoss would be to update the HttpClient that it ships with. This is a super-useful tool but version 3.0 has some much-needed improvements, and should be the standard, if that's possible.
And hopefully Java 6 will soon be the required Java for JBoss so it could stop shipping jaxb and many of the other things that are built-in to Java 6.
Hmm... I doubt JBoss will have a dependency on Java 6 any time in the near future. You might suggest the JAR updates in JIRA so the app server guys take notice.