Получение контекста из встроенного Glassfish 3.1 - PullRequest
5 голосов
/ 03 марта 2011

Есть ли у кого-нибудь сейчас способ получения контекста сервера с помощью Embeddable API (с использованием org.glassfish.embeddable.GlassFish, а не javax.ejb.embeddable.EJBContainer)?Было бы возможно, если бы был способ получить EJBContainer от работающей Glassfish, но я не могу найти даже список сервисов, доступных для поиска.

Ответы [ 2 ]

1 голос
/ 03 марта 2011

Вот обходной путь - мы можем получить 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 голосов
/ 05 октября 2011

Насколько я знаю, вы можете инициализировать класс InitialContext для получения контекста, который в дальнейшем можно будет использовать для поиска. Это было проверено и найдено работающим в контексте поиска EJB, развернутого во встроенном контейнере. EJB не был настроен для разрешения доступа к определенным ролям, в этом случае может помочь класс com.sun.appserv.security.ProgrammaticLogin (не предоставляемый через Embeddable EJB API); это не было проверено, но это рекомендуемый способ инициализации Principal для потока, обращающегося к EJB.

Ниже приведен более или менее полный пример, который запускается из Maven и использует встроенную зависимость Glassfish в 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;
    }

}

Модульный тест:

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 в других тестах, и более или менее сложно указать название приложения в таких тестах; каждое выполнение теста может приводить к различному имени JNDI для EJB, что требует указания явного имени JNDI.

...