7 Replies Latest reply on Jan 8, 2007 5:51 PM by norman.richards

    Dealing with JAR conflicts

    smokingapipe

      Here's the problem: My application is using Apache HttpClient to do various things. Unfortunately it absolutely relies on version 3.0 of HttpClient, and also unfortunately, JBoss 4.0.5 is packaged with an older version. When my application tries to call the setRequestEntity method, which doesn't exist in the older HttpClient, I get a NoSuchMethod exception of course.

      I have put the httpclient.jar inside my .ear file, and put in code like this:

      <module>
       <java>httpclient.jar</java>
       </module>

      in application.xml, but it doesn't help.

      Any ideas or solutions on this? Would it be safe for me to simply replace the
      ./lib/commons-httpclient.jar
      ./client/commons-httpclient.jar
      ./server/default/lib/commons-httpclient.jar

      files with the more recent JAR? I assume it would be safe because the current JAR is backward-compatible with the older versions.


        • 1. Re: Dealing with JAR conflicts
          smokingapipe

          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.

          • 2. Re: Dealing with JAR conflicts
            smokingapipe

            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.

            • 3. Re: Dealing with JAR conflicts
              smokingapipe

              I had it print out the classloader in question, and got:

              org.jboss.mx.loading.UnifiedClassLoader3@3a396fce{ url=file:/usr/java/jboss/server/default/tmp/deploy/tmp2172MyApp.ear
              


              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?


              • 4. Re: Dealing with JAR conflicts
                smokingapipe

                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?

                • 5. Re: Dealing with JAR conflicts

                  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>
                  


                  • 6. Re: Dealing with JAR conflicts
                    smokingapipe

                    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.

                    • 7. Re: Dealing with JAR conflicts

                      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.