Friday, March 22, 2013

JBoss 4.2.2 GA to JDK 7 (or JDK 6) migration

    JBoss 4.2.2 GA was released long time ago. Despite that fact, some mature projects that run in production are deployed on mentioned JBoss. JBoss 4.2.2 GA is quite old, however it can be hosted on JDK7. Some minor changes are necessary, but they can be introduced quite easy. I decided to create this migration guide in order to save someone's day.
I had to deal with two major problems. First one occurred during start up phase of JBoss 4.2.2 GA on JDK7 with EAR file that contained our application. Beautiful exception appeared in server's logs. It was potentially connected with JAXB:
java.lang.IllegalStateException: Cannot build JAXB context
 at org.jboss.ws.metadata.builder.jaxws.JAXWSMetaDataBuilder
.createJAXBContext(JAXWSMetaDataBuilder.java:955)
 at org.jboss.ws.metadata.builder.jaxws.JAXWSWebServiceMetaDataBuilder
.buildWebServiceMetaData(JAXWSWebServiceMetaDataBuilder.java:156)
 at org.jboss.ws.metadata.builder.jaxws.JAXWSServerMetaDataBuilder
.setupProviderOrWebService(JAXWSServerMetaDataBuilder.java:52)
 at org.jboss.ws.metadata.builder.jaxws.JAXWSMetaDataBuilderEJB3
.buildMetaData(JAXWSMetaDataBuilderEJB3.java:78)
 at org.jboss.wsf.stack.jbws.UnifiedMetaDataDeploymentAspect
.create(UnifiedMetaDataDeploymentAspect.java:71)
...
Caused by: org.jboss.ws.WSException: Failed to create JAXBContext
 at org.jboss.ws.core.jaxws.CustomizableJAXBContextFactory
.createContext(CustomizableJAXBContextFactory.java:116)
 at org.jboss.ws.metadata.builder.jaxws.JAXWSMetaDataBuilder
.createJAXBContext(JAXWSMetaDataBuilder.java:951)
 ... 82 more
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 
1 counts of IllegalAnnotationExceptions
java.lang.StackTraceElement does not have a no-arg default constructor.
 this problem is related to the following location:
  at java.lang.StackTraceElement
  at public java.lang.StackTraceElement[] java.lang.Throwable.getStackTrace()
  at java.lang.Throwable
  at private java.lang.Throwable[] myinterfaces.jaxws.ApplicationExceptionBean.suppressed
  at myinterfaces.jaxws.ApplicationExceptionBean
 at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder
.check(IllegalAnnotationsException.java:102)
 at com.sun.xml.bind.v2.runtime.JAXBContextImpl
.getTypeInfoSet(JAXBContextImpl.java:438)
 at com.sun.xml.bind.v2.runtime.JAXBContextImpl
.(JAXBContextImpl.java:286)
 at com.sun.xml.bind.v2.ContextFactory
.createContext(ContextFactory.java:139)
 at com.sun.xml.bind.api.JAXBRIContext
.newInstance(JAXBRIContext.java:105)
 at org.jboss.ws.core.jaxws
.CustomizableJAXBContextFactory.createContext(CustomizableJAXBContextFactory.java:110)
 ... 83 more
Two important clues from the stacktrace are made bold. After skimming through JBoss JIRA, I managed to find out that the problem was with JBossWS Native implementation: JIRA comment. There is the commit that solves the problem connected with the fact that getSuppressed() method was added to Throwable in JDK7. Everything was clear now, but our JBoss 4.2.2 GA works with JBossWS Native 3.0.1-native-2.0.4.GA. Upgrading WS provider to the jbossws-native-3.1.2 was not an option because of the risk. I decided to solve the problem in a different way. I downloaded the source code of the JBossWS Native 3.0.1-native-2.0.4.GA and I added the following line:
excludedGetters.add("getSuppressed");
to the org.jboss.ws.core.jaxws.AbstractWrapperGenerator class (as it is seen in the presented commit). Next, I compiled that class in isolation (meaning that I placed AbstractWrapperGenerator in a separate folder together with classes/interfaces referenced from that class and I used javac to obtain AbstractWrapperGenerator.class) and I injected AbstractWrapperGenerator.class into jbossws-core.jar (you can use e.g. Total Commander to do that [just remember about the license]). JBoss 4.2.2 GA started on JDK7 without any errors. Everything seemed fine until first SOAP request which resulted in:
java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage
 at javax.xml.soap.SOAPMessage.setProperty(SOAPMessage.java:439)
 at org.jboss.ws.core.soap.SOAPMessageImpl.(SOAPMessageImpl.java:83)
 at org.jboss.ws.core.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:217)
 at org.jboss.ws.core.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:195)
 at org.jboss.wsf.stack.jbws.RequestHandlerImpl.processRequest(RequestHandlerImpl.java:447)
 at org.jboss.wsf.stack.jbws.RequestHandlerImpl.handleRequest(RequestHandlerImpl.java:284)
 at org.jboss.wsf.stack.jbws.RequestHandlerImpl.doPost(RequestHandlerImpl.java:201)
 at org.jboss.wsf.stack.jbws.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:134)
 at org.jboss.wsf.stack.jbws.EndpointServlet.service(EndpointServlet.java:84)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
        ...
It was the second problem. This exception is related to the fact that JDK7 (as well as JDK6) is shipped with JAX-WS implementation (Metro) and the newer version of JAX-WS has additional methods defined in the interfaces. JVM bootstrap classloader takes the precedence over application classloader and it loads JAX-WS interfaces from rt.jar. However, JVM has, so called, endorsed mechanism, which allows to load particular classes before classes from rt.jar. JBoss 4.2.3-GA-jdk6 was migrated to JDK 6 with the use of that mechanism. After copying the following files:

jboss-saaj.jar, 
jboss-jaxrpc.jar, 
jboss-jaxws.jar,
jboss-jaxws-ext.jar, 
jaxb-api.jar 

from jboss/server/default/lib and jboss/lib to jboss/lib/endorsed directory everything started to work properly.

I hope it will help someone.

14 comments :

  1. Where can I find jboss-saaj.jar,
    jboss-jaxrpc.jar,
    jboss-jaxws.jar,
    jboss-jaxws-ext.jar,
    jaxb-api.jar

    these file?

    ReplyDelete
    Replies
    1. I've just updated the description. Thanks for your comment!

      Delete
  2. Thank you very much!
    Great blog entry, helped a lot (also with a JBoss 4.2.3).

    Two more practical notes:
    1) I had to patch the jbossws-core-native.jar in deploy/jbossws.sar directory.

    2) The org.jboss.ws.core.jaxws.AbstractWrapperGenerator has not been changed between JBossWS 3.0.5GA and JBossWS 3.1.1 GA, thus possible also since JBossWS 3.0.1

    ReplyDelete
    Replies
    1. I am happy that I could help you :).

      Delete
  3. Our legacy apps now run with jdk 7. Thank you very much for your help :)

    ReplyDelete
  4. I have just tried configuring 4.2.2GA with JDK7 and it seems to start and work fine? After I have made the modification to the jbossws-core.jar I'm getting the below errors. Any Idea how is this possible? Also I can't find jboss-jaxws-ext.jar anywhere in the kit?

    Thanks

    18:43:02,774 WARN [ServiceController] Problem starting service jboss.beans:service=JBossBeanDeploym
    ent,name='jbossws.sar#jbossws.beans'
    org.jboss.deployment.DeploymentException: Cannot start AbstractKernelDeployment@45cd14f7{name=file:/
    H:/Jboss/jboss-4.2.2.GA/server/default/deploy/jbossws.sar/jbossws.beans/META-INF/jboss-beans.xml


    *** DEPLOYMENTS IN ERROR:
    WSSubscriptionManager -> java.lang.ClassNotFoundException: No ClassLoaders found for: org.jboss.ws.e
    xtensions.eventing.mgmt.SubscriptionManager
    WSNativeUnifiedMetaDataDeploymentAspect -> java.lang.NoClassDefFoundError: org/jboss/ws/metadata/bui
    lder/jaxrpc/JAXRPCServerMetaDataBuilder
    WSJAXBIntroDeploymentAspect -> java.lang.NoClassDefFoundError: org/jboss/ws/core/jaxws/JAXBBindingCu
    stomization
    WSNativeServiceEndpointInvokerDeploymentAspect -> java.lang.NoClassDefFoundError: org/jboss/ws/core/
    server/ServiceEndpointInvokerEJB21

    ReplyDelete
    Replies
    1. If it works fine for your technology stack - I would not change anything.

      jboss-jaxws-ext.jar can be found in JBoss 4.2.3 GA but I do not remember if it is necessary to place it under jboss/lib/endorsed in JBoss 4.2.2 GA.

      I do not know how the modification of jbossws-core.jar which I mentioned about can make org.jboss.ws.e
      xtensions.eventing.mgmt.SubscriptionManager class unavailable. Are you sure that you compiled org.jboss.ws.core.jaxws.AbstractWrapperGenerator in isolation using javac from Java 7? Once you have it compiled you should place it inside jbossws-core.jar. The change is minor.

      Delete
    2. I am facing the same problem; were you able to resolve it? Could you please share the solution for it?

      Delete
    3. Simply read carefully everything from top to bottom.

      Delete
  5. I followed these steps and got the server up and running, thank you. When I try to connect with a client however I get this error:

    23:53:26,902 ERROR [[SessionServices]] Servlet.service() for servlet SessionServices threw exception
    java.lang.NoClassDefFoundError: org/jboss/logging/Logger
    at javax.xml.soap.FactoryLoader.(FactoryLoader.java:47)
    at javax.xml.soap.SOAPFactory.newInstance(SOAPFactory.java:64)
    at org.jboss.ws.core.soap.SOAPFactoryImpl.createElement(SOAPFactoryImpl.java:120)
    at org.jboss.ws.core.soap.EnvelopeBuilderDOM.build(EnvelopeBuilderDOM.java:116)
    at org.jboss.ws.core.soap.EnvelopeBuilderDOM.build(EnvelopeBuilderDOM.java:85)
    at org.jboss.ws.core.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:254)
    at org.jboss.ws.core.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:179)
    at org.jboss.ws.core.server.ServiceEndpoint.processRequest(ServiceEndpoint.java:197)
    at org.jboss.ws.core.server.ServiceEndpointManager.processRequest(ServiceEndpointManager.java:448)
    at org.jboss.ws.core.server.AbstractServiceEndpointServlet.doPost(AbstractServiceEndpointServlet.java:114)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
    at org.jboss.ws.core.server.AbstractServiceEndpointServlet.service(AbstractServiceEndpointServlet.java:75)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:525)
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
    at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:745)

    In 4.2.2 GA I had used log4j but this seems like jboss logging library? Any ideas? Thank you in advance.

    ReplyDelete
    Replies
    1. I figured this out from this link:
      https://issues.jboss.org/browse/JBWS-1439?focusedCommentId=12441415&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12441415
      I also had to find jboss-logging-spi.jar and add it to /lib/endorsed/
      My logging is not working as described in the link but my client is able to connect

      Delete
  6. Next, I compiled that class in isolation and I injected it into jbossws-core.jar.

    Can you explain the steps to perform this above statement.

    ReplyDelete
    Replies
    1. I placed additional description in the post. Please check this out and let me know if that helped.

      Delete