8 Replies Latest reply on Oct 10, 2006 12:34 PM by J-C jc

    Embedded EJB3 and .scanClasspath()

    darren hartford Expert

      I'm trying to use embedded EJB3 in an Eclipse RCP plugin. If this is not the correct forum, please direct me to the correct forum instead of ignoring this thread.

      I'm having some challenges related to loading my actual EJB3 classes. The default/non-Eclipse fashion involves using EJB3StandaloneBootstrap.scanClasspath() which I understand uses the 'java.class.path' system property. This is not valid for something like Eclipse RCP where seperate classloaders are involved.

      How do you specify to deploy your EJB3 classes without scanClasspath()? I have already looked at http://docs.jboss.org/ejb3/embedded/embedded.html and tried all the advanced-deployment tutorials, but they only detail persistence.xml deployments and have no examples related to EJB3 class deployments that may or may not be in the classpath/classloader.

      Can someone please assist?

      Thanks,
      -D

        • 1. Re: Embedded EJB3 and .scanClasspath()
          J-C jc Apprentice

          I have the same problem using maven. It uses several classpath. To solve this I have implemented a custom class embeddableejb3tools.EmbeddableEJB3Container(). Before starting the container I declare at least one session bean class. It will deploy all the classes deploy in the jar of this classes or in its directory. Following an example on how to use.

          EJB3Container container = new embeddableejb3tools.EmbeddableEJB3Container();
          container.getAccepted().add(
          container.getArchiveURL(MyService.class));
          container.startup();
          container.scan();
          container.shutdown();
          


          The code: 3 classes: an interface for the container, an impl for the EJB3 embeddable and an exception. It can probably be improved. If you do improvement please keep me inform.
          package embeddableejb3tools;
          
          import java.util.HashSet;
          
          import javax.naming.InitialContext;
          import javax.naming.NamingException;
          
          public interface EJB3Container {
          
           /**
           * Startup the embedd EJB3 container
           *
           * @throws Exception
           */
           public abstract void startup() throws Exception;
           public void scan() throws Exception;
          
           /**
           * Shutdown the embedded EJB3 container
           *
           */
           public abstract void shutdown();
          
           public abstract String getArchiveURL(Class clazz)
           throws InitializationException;
          
           public abstract InitialContext getInitialContext() throws NamingException;
          
           public abstract boolean accept(String file);
          
           public abstract HashSet<String> getAccepted();
          
           public abstract void setAccepted(HashSet<String> accepted);
          
           public abstract HashSet<String> getIgnored();
          
           public abstract void setIgnored(HashSet<String> ignored);
          
          }
          

          package embeddableejb3tools;
          
          import java.io.File;
          import java.lang.reflect.Field;
          import java.net.URL;
          import java.net.URLClassLoader;
          import java.util.ArrayList;
          import java.util.HashSet;
          import java.util.Hashtable;
          import java.util.Iterator;
          import java.util.List;
          
          import javax.naming.InitialContext;
          import javax.naming.NamingException;
          
          import org.jboss.ejb3.embedded.EJB3StandaloneBootstrap;
          
          import sun.misc.URLClassPath;
          
          /**
           *
           * @author walmetjc
           *
           */
          public class EmbeddableEJB3Container implements EJB3Container {
           private HashSet<String> accepted = new HashSet<String>();
          
           private HashSet<String> ignored = new HashSet<String>();
          
           private String originalProperty;
          
           /*
           * (non-Javadoc)
           *
           * @see embeddableejb3tools.EJB3Container#startup()
           */
           public void startup() throws Exception {
           initProperty();
           EJB3StandaloneBootstrap.boot(null);
           }
           public void scan() throws Exception {
           EJB3StandaloneBootstrap.scanClasspath();
           }
          
           /*
           * (non-Javadoc)
           *
           * @see embeddableejb3tools.EJB3Container#shutdown()
           */
           public void shutdown() {
           EJB3StandaloneBootstrap.shutdown();
           finalizeProperty();
           }
          
           protected void initProperty() {
           originalProperty = System.getProperty("java.class.path");
           System.getProperties().put("java.class.path", getPath());
           }
          
          
           protected void finalizeProperty() {
           System.getProperties().put("java.class.path", originalProperty);
          
           }
          
           /*
           * (non-Javadoc)
           *
           * @see embeddableejb3tools.EJB3Container#getArchiveURL(java.lang.Class)
           */
           public String getArchiveURL(Class clazz) throws InitializationException {
           try {
           String className = "/" + clazz.getCanonicalName().replace('.', '/')
           + ".class";
           URL url = getClass().getResource(className);
           String urlName = url.getFile();
           int i = urlName.indexOf('!');
           if (i != -1) {
           String jarName = urlName.substring(0, i);
           URL jarUrl = new URL(jarName);
           return jarUrl.getFile();
           } else {
           int j = urlName.indexOf(className);
           String jarName = urlName.substring(0, j + 1);
           return jarName;
           }
          
           } catch (Exception e) {
           throw new InitializationException(
           "Unable to retrieve the archive containing " + clazz, e);
           }
           }
          
           /*
           * (non-Javadoc)
           *
           * @see .embeddableejb3tools.EJB3Container#getInitialContext()
           */
           public InitialContext getInitialContext() throws NamingException {
           Hashtable props = getInitialContextProperties();
           return new InitialContext(props);
           }
          
           private Hashtable getInitialContextProperties() {
           java.util.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;
           }
          
           // 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);
           }
           }
          
           protected String getPath() {
           List<URL> urls = getURLs((URLClassLoader) getClass().getClassLoader());
           Iterator<URL> iter = urls.iterator();
           String prop = "";// iter.next().getFile();
           while (iter.hasNext()) {
           String file = iter.next().getFile();
           if (accept(file)) {
           prop = prop + File.pathSeparator + file;
           }
           }
           return prop;
           }
          
           /*
           * (non-Javadoc)
           *
           * @see .embeddableejb3tools.EJB3Container#accept(java.lang.String)
           */
           public boolean accept(String file) {
           for (String pattern : getAccepted()) {
           if (file.matches(pattern)) {
           return true;
           }
           }
           for (String pattern : getIgnored()) {
           if (file.matches(pattern)) {
           return false;
           }
           }
           return false;
           }
          
           /*
           * (non-Javadoc)
           *
           * @see embeddableejb3tools.EJB3Container#getAccepted()
           */
           public HashSet<String> getAccepted() {
           return accepted;
           }
          
           /*
           * (non-Javadoc)
           *
           * @see embeddableejb3tools.EJB3Container#setAccepted(java.util.HashSet)
           */
           public void setAccepted(HashSet<String> accepted) {
           this.accepted = accepted;
           }
          
           /*
           * (non-Javadoc)
           *
           * @see embeddableejb3tools.EJB3Container#getIgnored()
           */
           public HashSet<String> getIgnored() {
           return ignored;
           }
          
           /*
           * (non-Javadoc)
           *
           * @see embeddableejb3tools.EJB3Container#setIgnored(java.util.HashSet)
           */
           public void setIgnored(HashSet<String> ignored) {
           this.ignored = ignored;
           }
          }
          

          package embeddableejb3tools;
          
          public class InitializationException extends RuntimeException {
          
           /**
           *
           */
           private static final long serialVersionUID = 5277895415289316574L;
          
           public InitializationException() {
           super();
           }
          
           public InitializationException(String message, Throwable cause) {
           super(message, cause);
           }
          
           public InitializationException(String message) {
           super(message);
           }
          
           public InitializationException(Throwable cause) {
           super(cause);
           }
          
          }
          


          • 2. Re: Embedded EJB3 and .scanClasspath()
            darren hartford Expert

            I tried the EmbeddableEJB3Container, but ran into more classloader issues (with Eclipse):


            java.lang.ClassCastException: org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader
             at embedded.ejb3.EmbeddableEJB3Container.getPath(EmbeddableEJB3Container.java:136)
             at embedded.ejb3.EmbeddableEJB3Container.initProperty(EmbeddableEJB3Container.java:57)
             at embedded.ejb3.EmbeddableEJB3Container.startup(EmbeddableEJB3Container.java:38)
            


            • 3. Re: Embedded EJB3 and .scanClasspath()
              J-C jc Apprentice

              getPath() method is in charge to return the classpath as a String.

              When I run testcase under Eclipse or with maven, the classpath is an URLClasspath. I wrote the line :

              List<URL> urls = getURLs((URLClassLoader) getClass().getClassLoader());
              


              In your case it looks that it is not an URLClassLoader but a DefaultClassLoader. You need to find a way to get the classpath from this classloader.

              I have no idea on how eclipse RCP manages it classloader.

              • 4. Re: Embedded EJB3 and .scanClasspath()
                darren hartford Expert

                Overall, this sounds like another approach I was trying to do within the EJB3 embed library:

                EJB3StandaloneBootstrap.boot(null);
                //EJB3StandaloneBootstrap.scanClasspath();
                EJB3StandaloneDeployer deployer = EJB3StandaloneBootstrap.createDeployer();
                
                ClassLoader cl2 = MySessionBean.class.getClassLoader();
                
                deployer.setClassLoader(cl2);
                ....
                


                Not sure if this may help as an alternative for your approach/problem, but I'm still stuck in Eclipse land without a solution just yet.

                • 5. Re: Embedded EJB3 and .scanClasspath()
                  darren hartford Expert

                  May be stretching, but not being able to use the EJB3StandaloneBootstrat.deployXXX related to this may help if also support Eclipse:

                  http://jira.jboss.com/jira/browse/JBCOMMON-6

                  • 6. Re: Embedded EJB3 and .scanClasspath()
                    Per Wiklander Newbie

                    Did anyone find a solution for this?

                    Doing this...

                    EJB3StandaloneBootstrap.boot(null);
                    EJB3StandaloneBootstrap.scanClasspath();
                    

                    ...gets me this far
                    DEBUG 08-10 17:36:02,421 (KernelFactory.java:assembleNewKernel:86) -Starting JBoss Kernel construction...
                    DEBUG 08-10 17:36:02,734 (KernelFactory.java:assembleNewKernel:112) -Completed JBoss Kernel construction. Duration: 297 milliseconds
                    WARN 08-10 17:36:03,781 (BeanSchemaBinding.java:init:233) -You should use the 2.0 version of the Microcontainer xml. xmlns='urn:jboss:bean-deployer:2.0'
                    DEBUG 08-10 17:36:04,109 (BeanXMLDeployer.java:deploy:91) -Parsing bundleresource://25/embedded-jboss-beans.xml took 1266 milliseconds
                    DEBUG 08-10 17:36:04,625 (UserTransactionImpl.java:start:61) -new UserTx: org.jboss.ejb3.embedded.UserTransactionImpl@1fb7cbb
                    INFO 08-10 17:36:04,828 (LocalTxDataSource.java:bindConnectionFactory:117) -Bound datasource to JNDI name 'java:/DefaultDS'
                    INFO 08-10 17:36:04,859 (LocalTxDataSource.java:bindConnectionFactory:117) -Bound datasource to JNDI name 'java:/VideoStoreDS'
                    DEBUG 08-10 17:36:04,859 (BeanXMLDeployer.java:deploy:98) -Deploying bundleresource://25/embedded-jboss-beans.xml took 2016 milliseconds
                    DEBUG 08-10 17:46:11,594 (JaccHelper.java:initialiseJacc:61) -Initialising JACC Context for deployment: startup
                    INFO 08-10 17:46:11,922 (Ejb3Deployment.java:create:309) -EJB3 deployment time took: 328
                    


                    so it obviously finds the .xml files in the root of the same classpath as where the EJB3 beans should be found. But when trying to get a service bean it isn't found, indicating that no classes where loaded (I guess they should've shown up in the log above as well).

                    InitialContext ctx;
                     MovieService movieService;
                     try
                     {
                     ctx = ContextFactory.getInitialContext();
                     movieService = (MovieService) ctx.lookup("MovieServiceBean/local");
                     }
                     catch (NamingException e)
                     {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                     }
                    


                    lookup
                     UserTransaction: org.jboss.ejb3.embedded.UserTransactionImpl
                    javax.naming.NameNotFoundException: MovieServiceBean 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:626)
                     at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:588)
                     at javax.naming.InitialContext.lookup(InitialContext.java:351)
                     at org.videostore.ui.view.SearchView.createPartControl(SearchView.java:123)
                     at org.eclipse.ui.internal.ViewReference.createPartHelper(ViewReference.java:332)
                     at org.eclipse.ui.internal.ViewReference.createPart(ViewReference.java:197)
                     at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:566)
                     at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:290)
                     at org.eclipse.ui.internal.ViewPane.setVisible(ViewPane.java:525)
                     at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:140)
                     at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:268)
                     at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
                     at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:394)
                     at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1144)
                     at org.eclipse.ui.internal.PartStack.setSelection(PartStack.java:1097)
                     at org.eclipse.ui.internal.PartStack.showPart(PartStack.java:1311)
                     at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:601)
                     at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:532)
                     at org.eclipse.ui.internal.PartSashContainer.createControl(PartSashContainer.java:562)
                     at org.eclipse.ui.internal.PerspectiveHelper.activate(PerspectiveHelper.java:244)
                     at org.eclipse.ui.internal.Perspective.onActivate(Perspective.java:815)
                     at org.eclipse.ui.internal.WorkbenchPage.onActivate(WorkbenchPage.java:2429)
                     at org.eclipse.ui.internal.WorkbenchWindow$6.run(WorkbenchWindow.java:2616)
                     at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:67)
                     at org.eclipse.ui.internal.WorkbenchWindow.setActivePage(WorkbenchWindow.java:2597)
                     at org.eclipse.ui.internal.WorkbenchWindow.busyOpenPage(WorkbenchWindow.java:658)
                     at org.eclipse.ui.internal.Workbench.busyOpenWorkbenchWindow(Workbench.java:795)
                     at org.eclipse.ui.internal.Workbench.doOpenFirstTimeWindow(Workbench.java:1437)
                     at org.eclipse.ui.internal.Workbench.openFirstTimeWindow(Workbench.java:1388)
                     at org.eclipse.ui.internal.WorkbenchConfigurer.openFirstTimeWindow(WorkbenchConfigurer.java:190)
                     at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:708)
                     at org.eclipse.ui.internal.Workbench.init(Workbench.java:1085)
                     at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1847)
                     at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:419)
                     at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
                     at org.videostore.ui.Application.run(Application.java:24)
                     at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
                     at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
                     at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
                     at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
                     at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
                     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.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
                     at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
                     at org.eclipse.core.launcher.Main.run(Main.java:977)
                     at org.eclipse.core.launcher.Main.main(Main.java:952)
                    


                    • 7. Re: Embedded EJB3 and .scanClasspath()
                      J-C jc Apprentice

                      Your service is in a jar or in a directory ?

                      • 8. Re: Embedded EJB3 and .scanClasspath()
                        J-C jc Apprentice

                        Sorry previous questin was stupid !

                        Do you have the jar or the dir containg your service in java.class.path ?