Embeddable API を使用して (org.glassfish.embeddable.GlassFish
ではなくを使用してjavax.ejb.embeddable.EJBContainer
) サーバー コンテキストを取得する方法はありますか? 実行中の Glassfish から EJBContainer を取得する方法があれば可能ですが、ルックアップできるサービスのリストすら見つかりません。
2 に答える
回避策は次のとおりです。 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の停止を妨げています...
私の知る限り、InitialContext
クラスを初期化してコンテキストを取得し、それをさらに使用してルックアップを実行できます。これはテスト済みで、埋め込みコンテナーにデプロイされた EJB をルックアップするコンテキストで機能することがわかっています。EJB は、特定のロールへのアクセスを許可するように構成されていcom.sun.appserv.security.ProgrammaticLogin
ませんでした。これはテストされていませんが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 名を指定する必要があります。