누구도 Embeddable API를 사용하여 서버 컨텍스트를 얻지 못합니까? org.glassfish.embeddable.GlassFish
이 아닌 javax.ejb.embeddable.EJBContainer
을 사용하고 있습니까? 실행중인 Glassfish에서 EJBContainer를 구할 수있는 방법이있을 수 있지만 검색에 사용할 수있는 서비스 목록조차 찾을 수 없습니다.임베디드 글래스 피쉬에서 컨텍스트 얻기 3.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 중지를 막은 후에도 실행 중입니다 ...
알고있는 한, InitialContext
클래스를 초기화하면 컨텍스트를 얻을 수 있습니다. 조회를 수행하는 데 사용됩니다. 이것은 테스트되었고, 임베디드 컨테이너에 배포 된 EJB를 찾는 맥락에서 작동하는 것으로 나타났습니다. 특정 역할에 대한 액세스를 허용하도록 EJB가 구성되지 않았기 때문에 com.sun.appserv.security.ProgrammaticLogin
클래스 (Embeddable EJB API를 통해 노출되지 않음)가 도움이 될 수 있습니다. 이것은 테스트되지 않았지만 EJB에 액세스하는 스레드에 대해 Principal
을 초기화하는 데 권장되는 방법입니다.
(간략화를 위해, 여기에서 재생되지 않는다) 메이븐에서 운영 및 POM에 내장 글래스 피시 종속성을 사용 다소 완벽한 예는 다음과 같다 :
는 EJB 인터페이스 :
public interface EchoManager
{
String echo(String message);
}
세션 콩 :
@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;
}
}
단위 테스트 : 나는 다른 테스트에서 공개 내장 가능한 EJB API를 사용하는 다른 검사를 같이 EJB가합니다 (@EJB
주석 통해) 명시 적 휴대용 JNDI 이름으로 배치되는 것을이
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 이름을 가져올 수 있으므로 명시 적으로 JNDI 이름을 지정해야합니다.