views:

18

answers:

1

I have two maven modules and a need for class A in module 1 to load class B in module 2 using class.forname. this works very well and I can call the right methods on class B no problem at all. module 1 is wired up using spring and I'd like to wire module 2 up in the same way for consistency. I tried this and compiled it up no issue. but when I try to run the code I get so many problems. First that it can't find various spring classes such as ApplicationContext. The dependencies exist in module 2's pom. to solve the problem I had to add all the spring jar's to my lib folder in JBoss.

Once they're added it seems to clear those issues, but then I get the following issue:-

org.springframework.beans.FatalBeanException: Class [org.springframework.beans.factory.xml.UtilNamespaceHandler] for namespace [http://www.springframework.org/schema/util] does not implement the [org.springframework.beans.factory.xml.NamespaceHandler] interface

and I can't understand why. Is what I am trying to do achieveable?

+1  A: 

This is not a problem of Maven or Spring, since both don't do any classpath magic. It is a problem of your deployment and packaging.

Verify that both modules are declared as being of scope runtime (or default) in your pom.xml. The .war or .ear you are packaging should contain both module jar files and their dependencies. Do never every copy any libraries to the server's lib folder, unless you really know what you're doing.

Also verify that your final archive must not contain duplicate entries! That is very important. In case you use Spring, make sure you have no spring.jar, but only the spring-xxxxx.jar files in your application archive. If you have for example spring-beans.jar and spring.jar, something's wrong in your dependency management in the poml.xml. Also remove the Spring libraries you added to the server's lib folder.

Verify the versions of your dependencies. Although Maven should protect you from most mistakes, ensure that you haven't got any library with multiple versions in your classpath.

If you are using Class.forName(String), you should instead of Class.forName(String,ClassLoader) and use the application's ClassLoader. Imho the default ClassLoader used by Class.forName() is the Thread's ContextClassLoader (TCCL). Not sure if this is the correct one for your case. If you use any framework which performs dynamic Class Loading or weaving etc, you may try to set the TCCL on your own.

Another option, if all fails, is to check whether you need to invert the ClassLoader delegation model of JBoss. See JBoss Class Loader HOW-TO

mhaller