glassfish
  1. glassfish
  2. GLASSFISH-17381

Deployment of ScatteredArchives fail when a META-INF/validation.xml is present in the classpath

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 3.1
    • Fix Version/s: None
    • Component/s: embedded
    • Labels:
      None

      Description

      The background of this issue can be found in the Arquillian project, in ticket ARQ-525.


      Summary

      The summary of the issue, is that when a META-INF/validation.xml file is present in the classpath of a Java application that starts embedded GlassFish, then the deployment might fail with an exception similar to the one listed below:

      5 Oct, 2011 7:32:01 PM org.glassfish.deployment.admin.DeployCommand execute
      SEVERE: Unable to parse META-INF/validation.xml
      javax.validation.ValidationException: Unable to parse META-INF/validation.xml
      	at org.hibernate.validator.xml.ValidationXmlParser.getValidationConfig(ValidationXmlParser.java:218)
      	at org.hibernate.validator.xml.ValidationXmlParser.parseValidationXml(ValidationXmlParser.java:60)
      	at org.hibernate.validator.engine.ConfigurationImpl.parseValidationXml(ConfigurationImpl.java:252)
      	at org.hibernate.validator.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:143)
      	at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:111)
      	at org.jvnet.hk2.config.WriteableView.<init>(WriteableView.java:104)
      	at org.jvnet.hk2.config.ConfigSupport.getWriteableView(ConfigSupport.java:214)
      	at org.jvnet.hk2.config.Transaction.enroll(Transaction.java:165)
      	at com.sun.enterprise.v3.server.ApplicationLifecycle.prepareAppConfigChanges(ApplicationLifecycle.java:1056)
      	at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:364)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:360)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1067)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1247)
      	at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1235)
      	at com.sun.enterprise.admin.cli.embeddable.CommandExecutorImpl.executeCommand(CommandExecutorImpl.java:118)
      	at com.sun.enterprise.admin.cli.embeddable.DeployerImpl.deploy(DeployerImpl.java:97)
      	at com.sun.enterprise.admin.cli.embeddable.DeployerImpl.deploy(DeployerImpl.java:88)
      	at com.acme.ejb.GreetingManagerTest.testGreetingWithGlassfishRuntime(GreetingManagerTest.java:90)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
      	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
      	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
      	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
      	at org.junit.rules.TestWatchman$1.evaluate(TestWatchman.java:48)
      	at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
      	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
      	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
      	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
      	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
      	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
      	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
      	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
      	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
      	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
      	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
      	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
      	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
      	at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
      	at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
      	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
      PlainTextActionReporterFAILUREDescription: deploy AdminCommandError occurred during deployment: Unable to parse META-INF/validation.xml. Please see server.log for more details.
          [name=glassfish-ejb-validation
      

      Analysis

      A detailed analysis of exception, revealed that the message "Unable to parse META-INF/validation.xml" is a bit misleading. In actuality, the ValidationException wraps a ClassNotFoundException for the class "com.sun.xml.bind.v2.ContextFactory". Deployment of applications were found to succeed in the following scenarios:

      1. deployment on a non-embeddded instance of Glassfish
      2. deployment using the embedded EJB container API i.e. javax.ejb.embeddable.EJBContainer, available since Java EE 6.

      Case (1) does not result in the exception, as the class is found in "jaxb-osgi.jar" under the installRoot/modules directory of a non-embedded Glassfish installation. Case (2) does not result in the exception, as HibernateValidator does not appear to be initialized when using the EJBContainer API class to deploy an application.

      The issue arises when the org.glassfish.embeddable.Deployer is used to deploy the application. Deploying an application in this manner triggers the use of Hibernate Validator, which in turn requires JAXB to validate the META-INF/validation.xml file found in the classpath. Embedded Glassfish contains the META-INF/services/javax.xml.bind.JAXBContext provider config file with the entry:

      com.sun.xml.bind.v2.ContextFactory
      

      This class (com.sun.xml.bind.v2.ContextFactory) is present in glassfish-embedded-all-3.1.jar, which is the code source of the system classloader. But, the loading of the class in the safeLoadClass method of the javax.xml.bind.ContextFinder class, fails to load the class, as only the root classloader is used to attempt loading the class. This is the root cause of the ClassNotFoundException, eventually caught and wrapped as a ValidationException.

      The attached testcase allows for a complete reproduction of the problem. The test case also demonstrates the inability to reproduce the exception in the two scenarios discussed:

      a. When jaxb-osgi.jar is registered as a codesource by a classloader, resulting in the ability to load the "ContextFactory" class in question.
      b. When the embedded EJB API is used to deploy the application.


      Steps to reproduce the problem

      1. Extract the attached test case.
      2. Comment the argLine element (line 49) in the pom.xml
      3. Run "mvn clean test" to obtain the exception when running test "testGreetingWithGlassfishRuntime". Note, the test "testGreetingWithEJBContainer" does not fail.
      4. Uncomment and run "mvn clean test" to run the tests without failure. The argLine element adds the directory containing "jaxb-osgi.jar" as an endorsed lib directory, to the JVM launched by Surefire.


      Possible workarounds deduced (could be incorrect or unfeasible, or others may exist):

      1. Embeddded Glassfish could document the version info of the "jaxb-osgi" dependency for every release, so that end-users may add a correct dependency to jaxb-osgi in the Surefire configuration, and also add it to the endorsed lib directory of a launched JVM.
      2. Embedded Glassfish could use the JAXB implementation within the JDK, instead of jaxb-osgi.
      3. Embedded Glassfish could avoid the use of jaxb-osgi (and similar dependencies that need to be present in the endorsed lib directory), and instead deploy all applications (WAR, EJB or otherwise) in the same manner as performed for the Java EE 6 embedded EJB API.

        Activity

        Hide
        sakshi.jain added a comment -

        The jaxb-api version to be used for 3.1.2 is 2.2.5 and for trunk is 2.2.2.

        Show
        sakshi.jain added a comment - The jaxb-api version to be used for 3.1.2 is 2.2.5 and for trunk is 2.2.2.
        Hide
        dwuysan added a comment -

        People start to rely on embedded container for unit testing (which starts to address the complain that testing Java EE is difficult). Accordingly, it is important to make sure that jsr 303 Validation api can be loaded hassle-free.

        Show
        dwuysan added a comment - People start to rely on embedded container for unit testing (which starts to address the complain that testing Java EE is difficult). Accordingly, it is important to make sure that jsr 303 Validation api can be loaded hassle-free.

          People

          • Assignee:
            Bhavanishankar
            Reporter:
            Vineet Reynolds
          • Votes:
            3 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated: