CMIS vs Weblogic

Two days ago my colleague faced with a next challenge: in Weblogic environment CMIS deployment fails with the following stacktrace:

        at weblogic.servlet.internal.WebAppModule.startContexts(
        at weblogic.servlet.internal.WebAppModule.start(
        at weblogic.application.internal.flow.ModuleStateDriver$
        at weblogic.application.utils.StateMachineDriver.nextState(
        at weblogic.application.internal.flow.ModuleStateDriver.start(
        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(
        at com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl.<clinit>(
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(
        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:

  1. com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl – part of rt.jar since Java6
  2. 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 = 


  protected static final Logger log = 

java.util.logging.Logger prevents creating two loggers with the same name but different resource bundles:

    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

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s