2011-03-03 109 views
5

获取上下文现在没有人的方式来获得使用嵌入式API服务器环境(使用org.glassfish.embeddable.GlassFish,不javax.ejb.embeddable.EJBContainer)? 这将是可能的,如果有一种方法从运行的Glassfish的获得的EJBContainer,但我无法找到可供查找服务的竟然榜上有名。从嵌入式Glassfish的3.1

回答

1

这里有一个解决方法 - 我们可以得到的InitialContext为外部客户端。 对于充分说明检查EJB_FAQ。这样,至少远程EJB可以进行测试:

所以完整的例子看起来像:

//Start GF 
GlassFishRuntime gfRuntime = GlassFishRuntime.bootstrap(); 
GlassFish gf = gfRuntime.newGlassFish(); 
gf.start(); 
//Deploy application with EJBs 
Deployer deployer = gf.getService(Deployer.class); 
String deployedApp = deployer.deploy(new File(...), "--force=true"); 
//Create InitialContext 
Properties props = new Properties(); 
props.setProperty("java.naming.factory.initial", 
    "com.sun.enterprise.naming.SerialInitContextFactory"); 
props.setProperty("java.naming.factory.url.pkgs", 
    "com.sun.enterprise.naming"); 
props.setProperty("java.naming.factory.state", 
    "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl"); 
props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost"); 
props.setProperty("org.omg.CORBA.ORBInitialPort", "3700"); 
InitialContext ic = new InitialContext(props); 
//Lookup EJBs 
ic.lookup(...) 
//Stop GF 
gf.stop(); 
gfRuntime.shutdown(); 
//CORBA stuck thread, have to kill it manually 
System.exit(0); 

注意有一个System.exit(0)结尾 - com.sun.corba.ee。 impl.javax.rmi.CORBA.Util.KeepAlive线程运行后,即使服务器停止后,防止JVM停止...

0

据我所知,你可以初始化InitialContext类获得一个上下文,可以进一步用于执行查找。这已经过测试,并且发现可以在查找部署在嵌入式容器中的EJB的情况下工作。该EJB没有被配置为允许访问特定的角色,在这种情况下,com.sun.appserv.security.ProgrammaticLogin类(通过嵌入式EJB API不暴露)可能会有所帮助;这没有经过测试,但是为访问EJB的线程初始化Principal是推荐的方法。

从Maven的运行,并使用在POM嵌入式Glassfish的依赖关系(在此没有再现,为了简洁)甲或多或少完整的例子如下:

的EJB接口:

public interface EchoManager 
{ 
    String echo(String message); 
} 

会话Bean:

@Local(EchoManager.class) 
@Stateless 
@EJB(name="java:global/glassfish-ejb-validation/EchoManager",beanInterface=EchoManager.class) 
public class EchoManagerBean implements EchoManager 
{ 

    public String echo(String message) 
    { 
     return message; 
    } 

} 

单元测试:

public class EchoManagerTest 
{ 

    @Rule 
    public TestName testMethod = new TestName(); 

    private static final Logger logger = Logger.getLogger(EchoManagerTest.class.getName()); 

    @Test 
    public void testEchoWithGlassfishRuntime() throws Exception 
    { 
     logger.info("Starting execution of test" + testMethod.getMethodName()); 

     GlassFish glassFish = null; 
     Deployer deployer = null; 
     String appName = null; 
     try 
     { 
      //Setup 
      BootstrapProperties bootstrapProps = new BootstrapProperties(); 
      GlassFishRuntime glassFishRuntime = GlassFishRuntime.bootstrap(bootstrapProps); 

      GlassFishProperties gfProps = new GlassFishProperties(); 

      glassFish = glassFishRuntime.newGlassFish(gfProps); 
      glassFish.start(); 

      deployer = glassFish.getDeployer(); 
      ScatteredArchive archive = new ScatteredArchive("glassfish-ejb-validation", Type.JAR); 
      archive.addClassPath(new File("target", "classes")); 
      archive.addClassPath(new File("target", "test-classes")); 

      appName = deployer.deploy(archive.toURI(), "--force=true"); 

      // Setup the context 
      InitialContext context = new InitialContext(); 

      //Execute (after lookup the EJB from the context) 
      EchoManager manager = (EchoManager) context.lookup("java:global/glassfish-ejb-validation/EchoManager"); 
      String echo = manager.echo("Hello World"); 

      //Verify 
      assertEquals("Hello World", echo); 
     } 
     finally 
     { 
      if(deployer != null && appName != null) 
      { 
       deployer.undeploy(appName); 
      } 
      if(glassFish != null) 
      { 
       glassFish.stop(); 
       glassFish.dispose(); 
      } 
      logger.info("Ending execution of test" + testMethod.getMethodName()); 
     } 
    } 
} 

注意,EJB部署有一个明确的便携式JNDI名称(通过@EJB注释),因为我有,在其他测试中使用公共嵌入式EJB API等检查,并在这样的测试中指定应用程序名称或多或少是困难的;每个测试执行都可能导致EJB的JNDI名称不同,因此必须指定明确的JNDI名称。