5

org.glassfish.embeddable.GlassFish现在有没有人使用 Embeddable API(使用,不是)获取服务器上下文的方法javax.ejb.embeddable.EJBContainer?如果有办法从正在运行的 Glassfish 获取 EJBContainer 是可能的,但我什至找不到可用于查找的服务列表。

4

2 回答 2

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 停止之后仍在运行...

于 2011-03-03T18:24:10.547 回答
0

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

下面是一个从 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 名称。

于 2011-10-05T12:38:21.993 回答