1 2 Previous Next 15 Replies Latest reply on Nov 14, 2007 4:48 AM by Carlo de Wolf

    EJB3 AppClient - tests now pass but there are issues

    Adrian Brock Master

      I've added the parsing to the ClientLauncher which revealed a number of
      other issues, "fixing" these now makes the ejb3 appclient tests pass.

      * HARDWIRING

      I had to hack the resolver to hardwire the schemalocation -> annotated class
      There must be a better way to do this?
      Perhaps we can include a META-INF/schema-binding.xml in the jar
      and jbossxb can look for this config at bootstrap/hotdeployment?

      ClientLauncher.java - YUCK! :-)

       /** The schema resolver */
       private static DefaultSchemaResolver resolver = (DefaultSchemaResolver) SingletonSchemaResolverFactory.getInstance().getSchemaBindingResolver();
      
       static
       {
       // FIXME hardwiring
       resolver.addClassBindingForLocation("application-client", ApplicationClient14DTDMetaData.class);
       resolver.addClassBindingForLocation("application-client_1_2.dtd", ApplicationClient14DTDMetaData.class);
       resolver.addClassBindingForLocation("application-client_1_3.dtd", ApplicationClient14DTDMetaData.class);
       resolver.addClassBindingForLocation("application-client_1_4.xsd", ApplicationClient14MetaData.class);
       resolver.addClassBindingForLocation("application-client_5.xsd", ApplicationClient5MetaData.class);
       resolver.addClassBindingForLocation("jboss-client", JBossClient5DTDMetaData.class);
       resolver.addClassBindingForLocation("jboss-client_3_0.dtd", JBossClient5DTDMetaData.class);
       resolver.addClassBindingForLocation("jboss-client_3_2.dtd", JBossClient5DTDMetaData.class);
       resolver.addClassBindingForLocation("jboss-client_4_0.dtd", JBossClient5DTDMetaData.class);
       resolver.addClassBindingForLocation("jboss-client_4_2.dtd", JBossClient5DTDMetaData.class);
       resolver.addClassBindingForLocation("jboss-client_5_0.dtd", JBossClient5DTDMetaData.class);
       resolver.addClassBindingForLocation("jboss-client_5_0.xsd", JBossClient5MetaData.class);
       }
      


      * PROFILE SERVICE

      Really we shouldn't be parsing the jar anyway.

      The profile service may override the configuration so we should have an option
      to retrieve the merged (and overridden) JBossClientMetaData from the server
      and bootstrap from there (including downloading the classes/jar?).

      Something like:

      ./jboss-client.ch server=hostname:1099 client=my.ear/some.car
      


      * MAIN

      I added the code to main() for the parsing, but the ejb3 testsuite doesn't test this?

      * PersistenceContextHandler

      I found the same problem that Scott had with Environment vs RemoteEnvironment
      "Fixed" it with a similar hack to the jndi binding described on the other thread.
      I guess there is some missing implementation here?

      +++ src/main/org/jboss/injection/PersistenceContextHandler.java (working copy)
      @@ -23,6 +23,7 @@
      
       import org.jboss.metadata.javaee.spec.Environment;
       import org.jboss.metadata.javaee.spec.PersistenceContextReferenceMetaData;
      +import org.jboss.metadata.javaee.spec.RemoteEnvironment;
       import org.jboss.logging.Logger;
       import org.jboss.annotation.IgnoreDependency;
      
      @@ -42,7 +43,7 @@
       * @version $Revision$
       * @Inject and create Injectors
       */
      -public class PersistenceContextHandler<X extends Environment> implements InjectionHandler<X>
      +public class PersistenceContextHandler<X extends RemoteEnvironment> implements InjectionHandler<X>
       {
       @SuppressWarnings("unused")
       private static final Logger log = Logger
      @@ -51,8 +52,10 @@
       public void loadXml(X xml, InjectionContainer container)
       {
       if (xml == null) return;
      - if (xml.getPersistenceContextRefs() == null) return;
      - for (PersistenceContextReferenceMetaData ref : xml.getPersistenceContextRefs())
      + if (xml instanceof Environment == false) return;
      + Environment env = (Environment) xml;
      + if (env.getPersistenceContextRefs() == null) return;
      + for (PersistenceContextReferenceMetaData ref : env.getPersistenceContextRefs())
       {
       String encName = "env/" + ref.getPersistenceContextRefName();
       // we add injection target no matter what. enc injection might be overridden but
      


      * TEST CLASSPATH

      Why is it necessary to add jars other than jbossall-client.jar to the classpath
      to run the client? See my comment in ejb3/build-test.xml

      I added jboss-metdata.jar which should be included (at least in part)
      in jbossall-client.jar?

       <path id="client.classpath">
       <pathelement path="${jboss.dist}/client/jbossall-client.jar"/>
      
       <!-- FIXME - shouldn't these be in jbossall-client.jar???? -->
       <path refid="apache.codec.classpath"/>
       <path refid="apache.log4j.classpath"/>
       <path refid="apache.logging.classpath"/>
       <path refid="jboss.test.classpath"/>
       <path refid="sun.servlet.classpath"/>
       <pathelement path="${jboss.dist}/client/jboss-ejb3-client.jar"/>
       <pathelement path="${jboss.dist}/lib/jboss-vfs.jar"/>
       <path refid="jboss.microcontainer.classpath"/>
       <path refid="jboss.metadata.classpath"/>
       </path>
      


      I'll leave Carlo to decide which of these issues needs further attention
      in the EJB3 project.

      We should probably raise a main appserver JIRA for the jbossall-client.jar issue?

        • 1. Re: EJB3 AppClient - tests now pass but there are issues
          Carlo de Wolf Master

          LOL, I got the appclient passing as well, but in a different way.

          I put the entire metaData in JNDI in the Ejb3ClientDeployer and retrieve it in the ClientLauncher.

          PersistenceContextHandler is removed from ClientContainer, because a client can't use one.

          Stop mucking up the generics. They are there for a reason (to find old smug). :-)

          • 2. Re: EJB3 AppClient - tests now pass but there are issues
            Adrian Brock Master

             

            "wolfc" wrote:

            Stop mucking up the generics. They are there for a reason (to find old smug). :-)


            You mean cause ClassCastExceptions that I don't understand. :-)

            • 3. Re: EJB3 AppClient - tests now pass but there are issues
              Adrian Brock Master

               

              "wolfc" wrote:

              PersistenceContextHandler is removed from ClientContainer, because a client can't use one.


              I'd have thought JPA is a valid client api, it's JavaSE?
              But then I'm not a big fan of client side -> tier 3 type nonsense. :-)

              • 4. Re: EJB3 AppClient - tests now pass but there are issues
                Carlo de Wolf Master

                Here's my ClientLauncher:
                I like it better, because it doesn't do any parsing and it uses server side metadata. So if you don't mind, I'll commit it.

                Index: /home/carlo/work/jboss-head/ejb3/src/main/org/jboss/ejb3/client/ClientLauncher.java
                ===================================================================
                --- /home/carlo/work/jboss-head/ejb3/src/main/org/jboss/ejb3/client/ClientLauncher.java (revision 67020)
                +++ /home/carlo/work/jboss-head/ejb3/src/main/org/jboss/ejb3/client/ClientLauncher.java (working copy)
                @@ -22,7 +22,6 @@
                 package org.jboss.ejb3.client;
                
                 import java.io.IOException;
                -import java.io.InputStream;
                 import java.net.URL;
                 import java.net.URLClassLoader;
                 import java.util.ArrayList;
                @@ -28,21 +27,17 @@
                 import java.util.ArrayList;
                 import java.util.List;
                
                +import javax.naming.InitialContext;
                +import javax.naming.NamingException;
                +
                 import org.jboss.client.AppClientLauncher;
                +import org.jboss.ejb3.metamodel.ApplicationClientDD;
                +import org.jboss.ejb3.metamodel.ApplicationClientDDObjectFactory;
                +import org.jboss.ejb3.metamodel.JBossClientDDObjectFactory;
                 import org.jboss.logging.Logger;
                -import org.jboss.metadata.client.jboss.JBossClient5DTDMetaData;
                -import org.jboss.metadata.client.jboss.JBossClient5MetaData;
                 import org.jboss.metadata.client.jboss.JBossClientMetaData;
                -import org.jboss.metadata.client.spec.ApplicationClient14DTDMetaData;
                -import org.jboss.metadata.client.spec.ApplicationClient14MetaData;
                -import org.jboss.metadata.client.spec.ApplicationClient5MetaData;
                -import org.jboss.metadata.client.spec.ApplicationClientMetaData;
                 import org.jboss.util.NotImplementedException;
                 import org.jboss.xb.binding.JBossXBException;
                -import org.jboss.xb.binding.Unmarshaller;
                -import org.jboss.xb.binding.UnmarshallerFactory;
                -import org.jboss.xb.binding.sunday.unmarshalling.DefaultSchemaResolver;
                -import org.jboss.xb.binding.sunday.unmarshalling.SingletonSchemaResolverFactory;
                
                 /**
                 * This class launches a JavaEE 5 application client.
                @@ -59,39 +54,6 @@
                 {
                 private static final Logger log = Logger.getLogger(ClientLauncher.class);
                
                - /** The unmarshaller factory */
                - private static UnmarshallerFactory factory = UnmarshallerFactory.newInstance();
                -
                - /** The schema resolver */
                - private static DefaultSchemaResolver resolver = (DefaultSchemaResolver) SingletonSchemaResolverFactory.getInstance().getSchemaBindingResolver();
                -
                - static
                - {
                - // FIXME hardwiring
                - resolver.addClassBindingForLocation("application-client", ApplicationClient14DTDMetaData.class);
                - resolver.addClassBindingForLocation("application-client_1_2.dtd", ApplicationClient14DTDMetaData.class);
                - resolver.addClassBindingForLocation("application-client_1_3.dtd", ApplicationClient14DTDMetaData.class);
                - resolver.addClassBindingForLocation("application-client_1_4.xsd", ApplicationClient14MetaData.class);
                - resolver.addClassBindingForLocation("application-client_5.xsd", ApplicationClient5MetaData.class);
                - resolver.addClassBindingForLocation("jboss-client", JBossClient5DTDMetaData.class);
                - resolver.addClassBindingForLocation("jboss-client_3_0.dtd", JBossClient5DTDMetaData.class);
                - resolver.addClassBindingForLocation("jboss-client_3_2.dtd", JBossClient5DTDMetaData.class);
                - resolver.addClassBindingForLocation("jboss-client_4_0.dtd", JBossClient5DTDMetaData.class);
                - resolver.addClassBindingForLocation("jboss-client_4_2.dtd", JBossClient5DTDMetaData.class);
                - resolver.addClassBindingForLocation("jboss-client_5_0.dtd", JBossClient5DTDMetaData.class);
                - resolver.addClassBindingForLocation("jboss-client_5_0.xsd", JBossClient5MetaData.class);
                - }
                -
                - private static URL findResource(String resourceName)
                - {
                - URL url;
                - if(Thread.currentThread().getContextClassLoader() instanceof URLClassLoader)
                - url = ((URLClassLoader) Thread.currentThread().getContextClassLoader()).findResource(resourceName);
                - else
                - url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
                - return url;
                - }
                -
                 /**
                 * Convenience method for launching a client container.
                 *
                @@ -121,8 +83,9 @@
                 * @throws IOException
                 * @throws JBossXBException
                 */
                - public static JBossClientMetaData loadXML() throws JBossXBException, IOException
                + public static JBossClientMetaData loadXML(String applicationClientName) throws NamingException
                 {
                + /*
                 URL url = findResource("META-INF/application-client.xml");
                 log.trace("application-client.xml found at " + url);
                 URL jbossClientURL = findResource("META-INF/jboss-client.xml");
                @@ -128,88 +91,11 @@
                 URL jbossClientURL = findResource("META-INF/jboss-client.xml");
                 log.trace("jboss-client.xml found at " + jbossClientURL);
                 return loadXML(url, jbossClientURL);
                - }
                -
                - @Deprecated
                - public static JBossClientMetaData loadXML(String urlSpec) throws JBossXBException, IOException
                - {
                - URL url = new URL(urlSpec);
                - return loadXML(url, null);
                - }
                -
                - public static Unmarshaller createUnmarshaller() throws JBossXBException, IOException
                - {
                - Unmarshaller unmarshaller = factory.newUnmarshaller();
                - unmarshaller.setSchemaValidation(true);
                - unmarshaller.setValidation(true);
                - return unmarshaller;
                -
                - }
                -
                - public static JBossClientMetaData loadXML(URL url, URL jbossClientURL) throws JBossXBException, IOException
                - {
                - if (url == null)
                - throw new RuntimeException("Null url for application-client.xml");
                -
                - log.debug("Parsing application-client.xml: "+url);
                - Unmarshaller unmarshaller = createUnmarshaller();
                - InputStream is = url.openStream();
                - Object parsed = null;
                - try
                - {
                - parsed = unmarshaller.unmarshal(is, resolver);
                - log.debug("Parsed application-client.xml: "+url+" to: "+parsed);
                - }
                - finally
                - {
                - try
                - {
                - is.close();
                - }
                - catch (Exception ignored)
                - {
                - }
                - }
                - if (parsed == null)
                - throw new JBossXBException("The xml " + url + " is not well formed!");
                -
                - ApplicationClientMetaData applicationClientMetaData = ApplicationClientMetaData.class.cast(parsed);
                -
                - JBossClientMetaData jbossClientMetaData;
                - if (jbossClientURL == null)
                - jbossClientMetaData = new JBossClientMetaData();
                - else
                - {
                -
                - log.debug("Parsing jboss-client.xml: "+jbossClientURL);
                - unmarshaller = createUnmarshaller();
                - is = jbossClientURL.openStream();
                - parsed = null;
                - try
                - {
                - parsed = unmarshaller.unmarshal(is, resolver);
                - log.debug("Parsed jboss-client.xml: "+jbossClientURL+" to: "+parsed);
                -
                - if (parsed == null)
                - throw new JBossXBException("The xml " + url + " is not well formed!");
                -
                - jbossClientMetaData = JBossClientMetaData.class.cast(parsed);
                - }
                - finally
                - {
                - try
                - {
                - is.close();
                - }
                - catch (Exception ignored)
                - {
                - }
                - }
                - }
                -
                - JBossClientMetaData result = new JBossClientMetaData();
                - result.merge(jbossClientMetaData, applicationClientMetaData, true);
                - return result;
                + */
                + log.warn("FIXME: using an unsupported hack to get metadata");
                + InitialContext ctx = new InitialContext();
                + JBossClientMetaData metaData = (JBossClientMetaData) ctx.lookup(applicationClientName + "/metaData");
                + return metaData;
                 }
                
                 /**
                @@ -241,8 +127,12 @@
                 URL appXmlURL = mainClass.getClassLoader().getResource("META-INF/application-client.xml");
                 if(appXmlURL == null)
                 throw new RuntimeException("Can't find META-INF/application-client.xml");
                - URL jbossXmlURL = mainClass.getClassLoader().getResource("META-INF/jboss-client.xml");
                - JBossClientMetaData xml = loadXML(appXmlURL, jbossXmlURL);
                +
                + // FIXME: client metadata
                + JBossClientMetaData xml = null;
                + //JBossClientMetaData xml = ApplicationClientDDObjectFactory.parse(appXmlURL);
                + if(true)
                + throw new RuntimeException("NYI");
                
                 // FIXME: j2ee.clientName
                
                @@ -275,7 +165,7 @@
                 public void launch(String mainClassName, String clientName, String args[])
                 throws Throwable
                 {
                - JBossClientMetaData xml = loadXML();
                + JBossClientMetaData xml = loadXML(clientName);
                 launch(xml, mainClassName, clientName, args);
                 }
                
                Index: /home/carlo/work/jboss-head/ejb3/src/main/org/jboss/ejb3/deployers/Ejb3ClientDeployer.java
                ===================================================================
                --- /home/carlo/work/jboss-head/ejb3/src/main/org/jboss/ejb3/deployers/Ejb3ClientDeployer.java (revision 66999)
                +++ /home/carlo/work/jboss-head/ejb3/src/main/org/jboss/ejb3/deployers/Ejb3ClientDeployer.java (working copy)
                @@ -84,6 +84,10 @@
                 // Notify the client launcher of extra class path entries in an EAR (See EE 8.2)
                 encCtx.bind("classPathEntries", getClassPathEntries(unit));
                
                + // TODO: Notify the client launcher of other metadata stuff (injectors, lifecycle callbacks etc)
                + // FIXME: For now I expose the entire metadata
                + encCtx.bind("metaData", metaData);
                +
                 String mainClassName = getMainClassName(unit, true);
                
                 Class<?> mainClass = loadClass(unit, mainClassName);


                • 5. Re: EJB3 AppClient - tests now pass but there are issues
                  Carlo de Wolf Master

                   

                  "adrian@jboss.org" wrote:
                  I'd have thought JPA is a valid client api, it's JavaSE?
                  But then I'm not a big fan of client side -> tier 3 type nonsense. :-)

                  By spec you can use a PersistenceUnit (see http://jira.jboss.com/jira/browse/EJBTHREE-1050). But Emmanuel doesn't like that, so he won't give me a remote persistence unit. :-)

                  • 6. Re: EJB3 AppClient - tests now pass but there are issues
                    Scott Stark Master

                     

                    "wolfc" wrote:
                    LOL, I got the appclient passing as well, but in a different way.

                    I put the entire metaData in JNDI in the Ejb3ClientDeployer and retrieve it in the ClientLauncher.

                    PersistenceContextHandler is removed from ClientContainer, because a client can't use one.

                    Stop mucking up the generics. They are there for a reason (to find old smug). :-)

                    I was working on this was well. I have also updated the ends with ".jar" to use the VFS to parse the manifest for the client main class.

                    Comparing the current ClientContainer/Ejb3ClientDeployer changes, I don't see the binding into jndi or the lookup of the metadata in the ClientLauncher. I see the ClientLauncher using the jbossxb binding framework to parse the descriptor to produce the new metadata instead. Are these changes checked in?


                    • 7. Re: EJB3 AppClient - tests now pass but there are issues
                      Scott Stark Master

                       

                      "adrian@jboss.org" wrote:

                      * TEST CLASSPATH

                      Why is it necessary to add jars other than jbossall-client.jar to the classpath
                      to run the client? See my comment in ejb3/build-test.xml

                      I added jboss-metdata.jar which should be included (at least in part)
                      in jbossall-client.jar?

                       <path id="client.classpath">
                       <pathelement path="${jboss.dist}/client/jbossall-client.jar"/>
                      
                       <!-- FIXME - shouldn't these be in jbossall-client.jar???? -->
                       <path refid="apache.codec.classpath"/>
                       <path refid="apache.log4j.classpath"/>
                       <path refid="apache.logging.classpath"/>
                       <path refid="jboss.test.classpath"/>
                       <path refid="sun.servlet.classpath"/>
                       <pathelement path="${jboss.dist}/client/jboss-ejb3-client.jar"/>
                       <pathelement path="${jboss.dist}/lib/jboss-vfs.jar"/>
                       <path refid="jboss.microcontainer.classpath"/>
                       <path refid="jboss.metadata.classpath"/>
                       </path>
                      


                      I'll leave Carlo to decide which of these issues needs further attention
                      in the EJB3 project.

                      We should probably raise a main appserver JIRA for the jbossall-client.jar issue?

                      The client container/launcher requires jboss-metadata.jar, jboss-container.jar (AbstractAnnotationImpl), and jboss-vfs.jar (for the vfs usage I added) to be in the client classpath as well.


                      • 8. Re: EJB3 AppClient - tests now pass but there are issues
                        Carlo de Wolf Master

                         

                        "scott.stark@jboss.org" wrote:
                        Comparing the current ClientContainer/Ejb3ClientDeployer changes, I don't see the binding into jndi or the lookup of the metadata in the ClientLauncher. I see the ClientLauncher using the jbossxb binding framework to parse the descriptor to produce the new metadata instead. Are these changes checked in?

                        Nope, it's the patch above (and then some). It overwrites the change made by Adrian. Shall I commit?

                        • 9. Re: EJB3 AppClient - tests now pass but there are issues
                          Scott Stark Master

                           

                          "wolfc" wrote:

                          Nope, it's the patch above (and then some). It overwrites the change made by Adrian. Shall I commit?

                          I would say yes.



                          • 10. Re: EJB3 AppClient - tests now pass but there are issues
                            Adrian Brock Master

                             

                            "wolfc" wrote:
                            Here's my ClientLauncher:
                            I like it better, because it doesn't do any parsing and it uses server side metadata. So if you don't mind, I'll commit it.


                            Go ahead, this is better (like I said above) because it will pick up the profile server
                            and deployer overrides to the metadata.

                            • 12. Re: EJB3 AppClient - tests now pass but there are issues
                              Scott Stark Master

                               

                              "adrian@jboss.org" wrote:
                              I've added the parsing to the ClientLauncher which revealed a number of
                              other issues, "fixing" these now makes the ejb3 appclient tests pass.

                              * HARDWIRING

                              I had to hack the resolver to hardwire the schemalocation -> annotated class
                              There must be a better way to do this?
                              Perhaps we can include a META-INF/schema-binding.xml in the jar
                              and jbossxb can look for this config at bootstrap/hotdeployment?

                              I would say only the launcher should look for this config file to avoid the usual problem of having defaults bundled in jars that end up conflicting with server config files like the metadata-beans.xml SchemaResolverConfig config.


                              • 13. Re: EJB3 AppClient - tests now pass but there are issues
                                Adrian Brock Master

                                 

                                "wolfc" wrote:
                                "adrian@jboss.org" wrote:
                                I'd have thought JPA is a valid client api, it's JavaSE?
                                But then I'm not a big fan of client side -> tier 3 type nonsense. :-)

                                By spec you can use a PersistenceUnit (see http://jira.jboss.com/jira/browse/EJBTHREE-1050). But Emmanuel doesn't like that, so he won't give me a remote persistence unit. :-)


                                Isn't it just a case of proxying the persistent context requests over remoting
                                and making sure the request handling on the server side runs
                                in any UserTransaction context created on the client?

                                I think we can do that in the appserver without hibernate having to implement it.

                                • 14. Re: EJB3 AppClient - tests now pass but there are issues
                                  Scott Stark Master

                                   

                                  log.warn("FIXME: using an unsupported hack to get metadata");


                                  So we need a plan on what the supported mechanism for configuring the client is.


                                  1 2 Previous Next