1 2 Previous Next 16 Replies Latest reply on Jul 27, 2006 11:51 AM by jc7442

    Embeddable EJB3 with Maven2?

    greening

      I've complained in Maven2-user mailing list that I've not been able to get Embeddable EJB3 Alpha 5 or Alpha3 to run under Maven2's unit test plugin called "Surefire". I registered a bug, and provided a demonstration application for the Maven folks (see JIRA ticket http://jira.codehaus.org/browse/SUREFIRE-38).

      Tantalizingly, however, someone posted that they've gotten it to work, but like Fermat's Last Theorem, they said it was too big to post. :) "Send me a note," the person said, "for the details." And so I sent a couple of notes, and nothing back. Gotta love it.

      So my question: Have you ever gotten EJB3 embeddable to work under Maven2/Surefire? If you have, would you mind terribly posting your pom.xml file, and maybe the JUnit test .java file you used?

      With the greatest hope and appreciation for your brilliance, I remain,

      Dan R. Greening

        • 1. Re: Embeddable EJB3 with Maven2?
          telegraph.road

          I see that you resolved your bug...
          but I cannot still get it working!

          I tryied to use the lastest jboss ejb3 embeddable (alpha7) and I modified your pom (they have semplified the dependency) and also your configuration files (they updated the conf directory too), but the test fails again...

          maven says:

          -------------------------------------------------------
           T E S T S
          -------------------------------------------------------
          Running org.jboss.tutorial.junit.EmbeddedEjb3TestCase
          WARN 31-05 01:11:02,955 (BeanSchemaBinding.java:init:227) -You should use the 2.0 version of the Microcontainer xml. xmlns='urn:jboss:bean-deployer:2.0'
          Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 3.489 sec <<< FAILURE!
          
          Results :
          Tests run: 2, Failures: 0, Errors: 2, Skipped: 0
          
          [INFO] ----------------------------------------------------------------------------
          [ERROR] BUILD FAILURE
          [INFO] ----------------------------------------------------------------------------
          [INFO] There are test failures.
          [INFO] ----------------------------------------------------------------------------
          [INFO] Trace
          org.apache.maven.BuildFailureException: There are test failures.
           at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:552)
           at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:472)
           at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:451)
           at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:303)
           at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:270)
           at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:139)
           at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:322)
           at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:115)
           at org.apache.maven.cli.MavenCli.main(MavenCli.java:249)
           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:585)
           at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
           at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
           at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
           at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
          Caused by: org.apache.maven.plugin.MojoFailureException: There are test failures.
           at org.apache.maven.plugin.surefire.SurefirePlugin.execute(SurefirePlugin.java:403)
           at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:415)
           at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:531)
           ... 16 more
          [INFO] ----------------------------------------------------------------------------
          


          can you help me?

          thanks,
          teo

          • 2. Re: Embeddable EJB3 with Maven2?
            greening

            You need to provide the stack trace from the actual test (not the Mojo dump). It should be in target/test-reports/something.txt.

            • 3. Re: Embeddable EJB3 with Maven2?
              telegraph.road

              thanks for the hint... I'm pretty new with maven!

              the error I have is :

              -------------------------------------------------------------------------------
              Test set: org.jboss.tutorial.junit.EmbeddedEjb3TestCase
              -------------------------------------------------------------------------------
              Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 3.489 sec <<< FAILURE!
              testEJBs(org.jboss.tutorial.junit.EmbeddedEjb3TestCase) Time elapsed: 0.014 sec <<< ERROR!
              javax.naming.NameNotFoundException: CustomerDAOBean not bound
               at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
               at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
               at org.jnp.server.NamingServer.getObject(NamingServer.java:543)
               at org.jnp.server.NamingServer.lookup(NamingServer.java:267)
               at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625)
               at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
               at javax.naming.InitialContext.lookup(InitialContext.java:351)
               at org.jboss.tutorial.junit.EmbeddedEjb3TestCase.testEJBs(EmbeddedEjb3TestCase.java:86)
              
              testEntityManager(org.jboss.tutorial.junit.EmbeddedEjb3TestCase) Time elapsed: 0.002 sec <<< ERROR!
              javax.naming.NameNotFoundException: custdb not bound
               at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
               at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
               at org.jnp.server.NamingServer.getObject(NamingServer.java:543)
               at org.jnp.server.NamingServer.lookup(NamingServer.java:296)
               at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625)
               at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
               at javax.naming.InitialContext.lookup(InitialContext.java:351)
               at org.jboss.tutorial.junit.EmbeddedEjb3TestCase.testEntityManager(EmbeddedEjb3TestCase.java:111)
              


              that seems like your old error...

              What I can do now?
              can you upload your lastest working project? I think I missed something...

              thanks,
              teo

              • 4. Re: Embeddable EJB3 with Maven2?
                greening

                I started to responding seriously, and then realized you can't really do it without looking at the full source code tree. :(

                • 5. Re: Embeddable EJB3 with Maven2?
                  bill.burke

                  It doesn't look like anything is being deployed.

                  Did you scan the classpath for your jars? scanClasspath? Maybe Maven screws up the java.class.path system property? If so, you will have to use the alternative mechanisms for deployment.

                  • 6. Re: Embeddable EJB3 with Maven2?
                    telegraph.road

                    Maven has several goals (task), that are in a precise order:
                    compile
                    test-compile
                    test
                    package

                    note that the package are created only if the project pass all tests...
                    now I want to use the jboss embeddable container in order to allow testing the project directly with maven. So it is possible to scan for javabeans present in the current classpath?

                    greening: what do you mean with "you can't really do it without looking at the full source code tree." ? I don't understand... :-(

                    thanks,
                    teo

                    • 7. Re: Embeddable EJB3 with Maven2?
                      greening

                      Bill's suggestion is probably right, but there are so many ways to screw up representation of which archive to look at. But there could also/instead be problems with your resource path, you could have used the wrong persistence.xml format (which changed).

                      Basically if you can't upload your source code tree somewhere, it will be hard to diagnose.

                      It's easy enough to find out who I am, google Dan R. Greening. Who are you? Am I helping a commercial company or an open source project?

                      • 8. Re: Embeddable EJB3 with Maven2?
                        telegraph.road

                        Well,
                        I'm an italian student (in september I will start my phd) at "Politecnico di Milano" (engineering / computer science), that is working on a university project.

                        For the source tree, I downloaded the file you attached the bug issue and tryied to modify it following your direction (in the bug comments you said something...).
                        The only thing I changed is the jboss-embedded version (I use the lastest alpha available, in order to be compatible with my existing project).

                        Now, I currently test my beans with ant, but I would use also maven2...
                        (so we can use our project's continuum server and integrate easily the various stundent's work).

                        I'm wondering if you can upload somewhere the lastest version of your simple code (the corrected version of the same sample you attached to the bug issue), so I can see how you get it working...

                        Thanks,
                        teo

                        • 9. Re: Embeddable EJB3 with Maven2?
                          jc7442

                          I had the same problem:
                          http://www.jboss.com/index.html?module=bb&op=viewtopic&t=82909

                          To workaround I wrote an horrible class. Have a look to the comment for checkPersistenceXML.
                          I think that there is some comment in the class. If that's not clear, I'll try to explian more precisely my problem. With that hoorible hook I'm able to run my testcase with maven and eclipse.

                          With maven ejb3 are not yet in jar files. For me there is a bug persistence.xml and ejb-jar.xml are not searched in directory, only in jar files. That's why I need to copy xml in another directory.
                          The other problem was that with maven maven uses classloader (java.class.path is not he classpath used). Consequently automatic scan does not works. That's why I need to declare explicitely jar and directories to scan.

                          import java.io.File;
                          import java.io.FileReader;
                          import java.io.FileWriter;
                          import java.io.IOException;
                          import java.lang.reflect.Field;
                          import java.net.URL;
                          import java.net.URLClassLoader;
                          import java.util.ArrayList;
                          import java.util.Hashtable;
                          import java.util.List;
                          
                          import javax.naming.InitialContext;
                          import javax.naming.NamingException;
                          
                          import junit.framework.TestCase;
                          
                          import org.apache.commons.logging.Log;
                          import org.apache.commons.logging.LogFactory;
                          import org.jboss.ejb3.embedded.EJB3StandaloneBootstrap;
                          import org.jboss.ejb3.embedded.EJB3StandaloneDeployer;
                          
                          import sun.misc.URLClassPath;
                          
                          /**
                           * Tas de boue .......
                           *
                           *
                           */
                          public class EmbeddableEJB3TestCase extends TestCase {
                           private boolean scanJars = false;
                          
                           private boolean scanDirs = true;
                          
                           private final Log LOGGER = LogFactory.getLog(EmbeddableEJB3TestCase.class
                           .getName());
                          
                           private List<File> tempFiles = new ArrayList<File>();
                          
                           @Override
                           protected void setUp() throws Exception {
                           EJB3StandaloneBootstrap.boot(null);
                           // scanClasspath method scan ejb to deplot using java.class.path.
                           // Unfortunately with maven this classpath
                           // does not contain the class of the project. Consequently the abominable
                           // hook is to deploy class using the deployer.
                           // EJB3StandaloneBootstrap.scanClasspath();
                           EJB3StandaloneDeployer deployer = initDeployer();
                           deployer.create();
                           deployer.start();
                          
                           // End of the abominable hook
                           }
                          
                           protected EJB3StandaloneDeployer initDeployer() throws Exception {
                           EJB3StandaloneDeployer deployer = EJB3StandaloneBootstrap.createDeployer();
                          
                           URLClassLoader loader = (URLClassLoader) getClass().getClassLoader();
                           List<URL> urls = getURLs(loader);
                          
                           for (URL url : urls) {
                           boolean isUsed = false;
                           File file = new File(url.getFile());
                           if (file.isDirectory()) {
                           if (isScanDirs()) {
                           deployer.getDeployDirs().add(url);
                           isUsed = true;
                           // Another hook
                           List<File> files = checkPersistenceXML(deployer, file);
                           getTempFiles().addAll(files);
                           // END of another hook
                           }
                           } else if (file.isFile() && file.getName().endsWith(".jar")) {
                           if (isScanJars()) {
                           deployer.getArchives().add(url);
                           isUsed = true;
                           }
                           }
                           if (isUsed) {
                           LOGGER.info("Scan " + url + " for deploy in Embeddable EJB3 !");
                           } else {
                           LOGGER.debug(url + " is not used for deploy in Embeddable EJB3 !");
                           }
                           }
                          
                           return deployer;
                          
                           }
                          
                           @Override
                           protected void tearDown() throws Exception {
                           EJB3StandaloneBootstrap.shutdown();
                           for (File file : getTempFiles()) {
                           file.delete();
                           }
                           getTempFiles().clear();
                           }
                          
                           // In JDK1.5, it seems to be impossible to get the urls from the classloader
                           // using the API.
                           protected List<URL> getURLs(URLClassLoader loader) {
                           try {
                           Field ucp = URLClassLoader.class.getDeclaredField("ucp");
                           ucp.setAccessible(true);
                           URLClassPath path = (URLClassPath) ucp.get(loader);
                           URL[] urls = path.getURLs();
                           // Usage of a list instead of a Set in order not to change the order of
                           // the classpath
                           List<URL> list = new ArrayList<URL>();
                           for (URL url : urls) {
                           if (!list.contains(url)) {
                           list.add(url);
                           }
                           }
                           return list;
                           } catch (Exception e) {
                           throw new RuntimeException("Unable to get urls from classloader !", e);
                           }
                           }
                          
                           public InitialContext getInitialContext() {
                           Hashtable props = getInitialContextProperties();
                           try {
                           return new InitialContext(props);
                           } catch (NamingException e) {
                           fail("Unable to get the initial context !");
                           // fail throws an exception, it sould never go there.
                           throw new RuntimeException(
                           "fail throws an exception, it sould never go there.", e);
                           }
                           }
                          
                           private Hashtable getInitialContextProperties() {
                           Hashtable<String, String> props = new Hashtable<String, String>();
                           props.put("java.naming.factory.initial",
                           "org.jnp.interfaces.LocalOnlyContextFactory");
                           props.put("java.naming.factory.url.pkgs",
                           "org.jboss.naming:org.jnp.interfaces");
                           return props;
                           }
                          
                           public boolean isScanDirs() {
                           return scanDirs;
                           }
                          
                           public void setScanDirs(boolean scanDirs) {
                           this.scanDirs = scanDirs;
                           }
                          
                           public boolean isScanJars() {
                           return scanJars;
                           }
                          
                           public void setScanJars(boolean scanJars) {
                           this.scanJars = scanJars;
                           }
                          
                           /**
                           * Hook: persistence.xml and ejb-jar.xml contains in deployement dierctories
                           * are not used by the standalone ejb3 deployer. Their directory needs to be
                           * added in the list of Jar files. If the directory containing annotated
                           * classes is added in jar files list, deployer send a warning. Consequently a
                           * fake directory containig only persistence.xml and ejb-jar.xml has to be
                           * created and added to the deployer.
                           *
                           * That is horrible !!!
                           *
                           * @param deployer
                           * @param file
                           *
                           * @return List of files copied by this method
                           */
                           protected List<File> checkPersistenceXML(EJB3StandaloneDeployer deployer,
                           File file) throws IOException {
                           // Init the list of created file in this method
                           List<File> createdFiles = new ArrayList<File>();
                          
                           final String META_INF = "META-INF/";
                           final String PERSISTENCE_XML = META_INF + "persistence.xml";
                           final String EJB_JAR_XML = META_INF + "ejb-jar.xml";
                           // XML will be added in the temp directory
                           List<File> treeFiles = getPathFiles(file);
                           String ROOT_DIR = System.getProperty("java.io.tmpdir") + "/ejb3.tests/";
                           String TEMP_DIR = ROOT_DIR + getFileName(file);
                          
                           // Check if xml have to be copied
                           File persistence = new File(file, PERSISTENCE_XML);
                           File ejb = new File(file, EJB_JAR_XML);
                          
                           if (persistence.exists() || ejb.exists()) {
                           // TempFile are used in order to be automatically deleted when JVM exits.
                           File dirFile = new File(TEMP_DIR);
                           if (dirFile.exists()) {
                           // If directory contains files or subdirectory throw an exception
                           if (!dirFile.delete()) {
                           throw new RuntimeException("Danger: Directory " + dirFile
                           + " should not exists !!! Delete it manually !");
                           }
                           }
                           dirFile.mkdirs();
                           File metainf = new File(dirFile, META_INF);
                           metainf.mkdir();
                           if (persistence.exists()) {
                           createdFiles.add(copyFile(persistence, metainf));
                           }
                           if (ejb.exists()) {
                           createdFiles.add(copyFile(ejb, metainf));
                           }
                          
                           deployer.getArchives().add(dirFile.toURL());
                           createdFiles.add(metainf);
                           for (File ff : treeFiles) {
                           File dir = new File(ROOT_DIR, getFileName(ff));
                           createdFiles.add(dir);
                           }
                           }
                           return createdFiles;
                           }
                          
                           protected File copyFile(File src, File targetDir) throws IOException {
                           LOGGER.info("Copy " + src + " to " + targetDir);
                           FileReader reader = new FileReader(src);
                           File dest = new File(targetDir, src.getName());
                           dest.createNewFile();
                           FileWriter writer = new FileWriter(dest);
                           int r = 0;
                           while ((r = reader.read()) != -1) {
                           writer.write(r);
                           }
                           writer.flush();
                           writer.close();
                           reader.close();
                           return dest;
                           }
                          
                           protected List<File> getTempFiles() {
                           return tempFiles;
                           }
                          
                           protected void setTempFiles(List<File> tempFiles) {
                           this.tempFiles = tempFiles;
                           }
                          
                           /**
                           * Return the list of files for the path structure
                           *
                           * @param f
                           * @return
                           */
                           protected List<File> getPathFiles(File f) {
                           List<File> files = new ArrayList<File>();
                           if (f.isDirectory()) {
                           files.add(f);
                           }
                           File parent = f;
                           while (parent != null) {
                           parent = parent.getParentFile();
                           // Drivers letter is excluded from the list
                           if (parent != null && parent.getParentFile() != null) {
                           files.add(parent);
                           }
                           }
                           return files;
                           }
                          
                           protected <T> T getService(Class<T> interfac) {
                           try {
                           InitialContext ctx = getInitialContext();
                           T local = (T) ctx.lookup("/" + interfac.getSimpleName() + "/local");
                           return local;
                           } catch (NamingException e) {
                           throw new RuntimeException("Unable to retieve service !", e);
                           }
                           }
                          
                           protected String getFileName(File f) {
                           return f.getPath().substring(2);
                           }
                          }
                          


                          • 10. Re: Embeddable EJB3 with Maven2?
                            telegraph.road

                            I still have some problems...
                            now, with EmbeddableEJB3TestCase, my embeddable jboss can see the various files, and start correctly the various ejbs.
                            But it hangs when I run the sample junit test (that was originally provided by the embedded-jboss tutorial)...

                            I uploaded the resulting zip here: http://cormano.ath.cx/maven-ejb.zip (when my university will activate my web space, I'll move it)

                            If anybody can help me in solving this throubles, I'll be very thankful!

                            thanks, teo

                            ps. the class "EmbeddableEJB3TestCase" is now in test-source-folter as "maven.jboss.junit.AbstractJeeTestCase"

                            • 11. Re: Embeddable EJB3 with Maven2?
                              jc7442

                              try to modify the persistence.xml to add the definition of the customer:

                              <persistence>
                               <persistence-unit name="custdb">
                               <jta-data-source>java:/DefaultDS</jta-data-source>
                               <class>simple.test.Customer</class>
                               <properties>
                               <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
                               </properties>
                               </persistence-unit>
                              </persistence>
                              


                              The first test is now ok. (not the second one)

                              • 12. Re: Embeddable EJB3 with Maven2?
                                jc7442

                                According to JBoss name, the managed entity manager is not deployed by default. To deploy it you need to specifiy the property jboss.entity.manager.jndi.name

                                With the following persistentce.xml it should works:

                                <persistence>
                                 <persistence-unit name="custdb">
                                 <jta-data-source>java:/DefaultDS</jta-data-source>
                                 <class>simple.test.Customer</class>
                                 <properties>
                                 <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
                                 <property name="jboss.entity.manager.jndi.name" value="java:/custdb"/>
                                 </properties>
                                 </persistence-unit>
                                </persistence>


                                • 13. Re: Embeddable EJB3 with Maven2?
                                  telegraph.road

                                  Thanks!
                                  Now the simple test is working...

                                  But I'm wondering why I have to specify all entity beans in my project... when I deploied the ejb-jar to the "real" jboss AS, I have never specified what entity beans are present in the project, but the application server discovers automatically (correctly) all entity beans I created... it is a maven building problem or a embeddable jboss problem (or a my failure?)

                                  Thanks all,
                                  Matteo

                                  • 14. Re: Embeddable EJB3 with Maven2?
                                    jc7442

                                    I think that problem comes from the way EJB3 are deploy in my class. When you use EJB3StandaloneBootstrap.scanClasspath(), you do not need to add classes in persistence.xml.

                                    From my point of view, it'll be better if scanClasspath method would be based on urls in classloader instead of being based from classpath in java.class.path property.

                                    1 2 Previous Next