Two days ago my colleague faced with a next challenge: in Weblogic environment CMIS deployment fails with the following stacktrace:
weblogic.application.ModuleException: at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1520) at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:484) at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:425) at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:52) at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:119) Truncated. see log file for complete stacktrace Caused By: java.lang.IllegalArgumentException: com.sun.xml.internal.messaging.saaj.soap.LocalStrings != com.sun.xml.messaging.saaj.soap.LocalStrings at java.util.logging.Logger.getLogger(Logger.java:369) at com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl.<clinit>(SAAJMetaFactoryImpl.java:52) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) Truncated. see log file for complete stacktrace
The root cause of this error is following:
there are to classes which extend javax.xml.soap.SAAJMetaFactory:
- com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl – part of rt.jar since Java6
- com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl – part of saaj-impl.jar which is shipped with emc-cmis-wls.ear/emc-cmis-weblogic.ear
both classes do following:
protected static final Logger log = Logger.getLogger("javax.xml.messaging.saaj.soap", "com.sun.xml.internal.messaging.saaj.soap.LocalStrings");
and
protected static final Logger log = Logger.getLogger("javax.xml.messaging.saaj.soap", "com.sun.xml.messaging.saaj.soap.LocalStrings");
java.util.logging.Logger prevents creating two loggers with the same name but different resource bundles:
@CallerSensitive public static Logger getLogger(String name, String resourceBundleName) { Class<?> callerClass = Reflection.getCallerClass(); Logger result = demandLogger(name, resourceBundleName, callerClass); if (result.resourceBundleName == null) { // We haven't set a bundle name yet on the Logger, so it's ok to proceed. // We have to set the callers ClassLoader here in case demandLogger // above found a previously created Logger. This can happen, for // example, if Logger.getLogger(name) is called and subsequently // Logger.getLogger(name, resourceBundleName) is called. In this case // we won't necessarily have the correct classloader saved away, so // we need to set it here, too. // Note: we may get a MissingResourceException here. result.setupResourceInfo(resourceBundleName, callerClass); } else if (!result.resourceBundleName.equals(resourceBundleName)) { // We already had a bundle name on the Logger and we're trying // to change it here which is not allowed. throw new IllegalArgumentException(result.resourceBundleName + " != " + resourceBundleName); } return result; }
So, if Weblogic loads something SOAP-related (for example, by default weblogic loads wls-wsat application), instance of java.util.logging.Logger gets poisoned by com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl class and you are unable to use different implementation of javax.xml.soap.SAAJMetaFactory.
The solution is to add -Dweblogic.wsee.wstx.wsat.deployed=false to weblogic’s startup parameters