static {
AssertionBuilder builder;
for (Iterator providers = Service.providers(AssertionBuilder.class); providers
.hasNext();) {
builder = (AssertionBuilder) providers.next();
QName[] knownElements = builder.getKnownElements();
for (int i = 0; i < knownElements.length; i++) {
registerBuilder(knownElements[i], builder);
}
}
registerBuilder(XML_ASSERTION_BUILDER, new XMLPrimitiveAssertionBuilder());
}
And Neethi doesn't use sun.misc.Service but uses it's own utility class, org.apache.neethi.util. Service to do this. So if we look at the Service class, it looks for org.apache.neethi.builders.AssertionBuilder files using the classloader of the org.apache.neethi.builders.AssertionBuilder.
ClassLoader cl = null;
try {
// cls is AssertionBuilder.class in our case
cl = cls.getClassLoader();
} catch (SecurityException se) {
// Ooops! can't get his class loader.
}
// Can always request your own class loader. But it might be 'null'.
if (cl == null) cl = Service.class.getClassLoader();
if (cl == null) cl = ClassLoader.getSystemClassLoader();
So here is the catchy part. It looks for the service provider configuration files using the classloader of AssertionBuilder class. So if we want our our service providers, that is domain specific assertion builders to be found they should be in the class path of the class loader of AssertionBuilder class which is in the Axis2 lib. So in this case, the Rampart jars which contains service provide r configurations files also need to go to in the Axis2 lib. AssertionBuilder must be able to load those service provider classes which are listed in the org.apache.neethi.builders.AssertionBuilder files. So until we solve this problem, having a standalone Rampart module is not possible.
Then the second problems is as we have two modules Rampart and Rahas, and if we we ship them as standalone modules we may have to ship all the rampart jars and dependency jars in both of those modules as those modules have their separate class paths when deployed in Axis2. Anyway this is not a blocker and may not be much of a problem.
When talking about this topic, some people tend to think that loading the password callback classes is also an issue here but is not. So the issue is service password callback handlers are packed in the service's archive (.aar) and the service has a separate class loader. But Rampart/WSS4J which lives in a separate module class loader needs to load these classes to get the passwords for various functions. But this not a problem because this explicitly handled by Rampart. So if we look at the code snippet that loads password callback handlers in org.apache.rampart.util.RampartUtil#getPasswordCB()
.
String cbHandlerClass = rpd.getRampartConfig().getPwCbClass();
ClassLoader classLoader = msgContext.getAxisService().getClassLoader();
log.debug("loading class : " + cbHandlerClass);
Class cbClass;
try {
cbClass = Loader.loadClass(classLoader, cbHandlerClass);
} catch (ClassNotFoundException e) {
throw new RampartException("cannotLoadPWCBClass",
new String[]{cbHandlerClass}, e);
}
So as you can see this is not a problem regarding this issue.










2 comments:
Nandana
Since Neethi uses its own class to load JARs that it finds using the JAR ServiceProvider model, surely we can just improve Neethi so that it uses the Axis2 Classloader model?
Paul
Post a Comment