嵌入式JBoss EAP 6 / AS 7入门 [英] Getting started with embeddable JBoss EAP 6 / AS 7

查看:128
本文介绍了嵌入式JBoss EAP 6 / AS 7入门的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用规范(JSR 318:Enterprise JavaBeans,版本3.1,第22章:可嵌入的用法)中描述的EJBContainer.createEJBContainer API尝试可嵌入的JBoss,不是任何<使用JBoss特定API的href = http://shrubbery.mynetgear.net/c/display/W/Embedded+JBoss+and+Embedded+EJB3 rel = nofollow>各种前辈。



概述




  • 正常调用主方法时,会话Bean调用成功。但是似乎存在一些类加载问题,因为 java:jboss / UserTransaction 中的JNDI对象无法转换为javax.transaction.UserTransaction。

  • 所以我想 JBoss模块的类加载魔术在这里是必需的。经过我的尝试,createEJBContainer找不到任何EJBContainerProviders并抛出EJBException。



请注意,并非我所有的问题都需要阅读所有后续内容。细节。因此,如果这本书太多了,请看看问题部分。



环境



JBoss AS 7.1.1.Final(jboss-as-7.1.1.Final .zip,仅在standalone.xml中更改了仅记录conf的conf)。

(最初是实际目标环境的JBoss EAP 6.0.1 GA-相同的问题)

Oracle JDK 1.7.0_11 < br>
Windows 7 Prof 64位



详细信息



无状态会话bean



 包test.helloworld.impl; 

import javax.ejb.Remote;
import javax.ejb.Stateless;
import test.helloworld.api.HelloWorld;

@ Stateless
@ Remote(HelloWorld.class)
公共类HelloWorldBean实现HelloWorld
{
@Override
public String salute()
{
返回世界你好;
}
}

...及其业务界面:

 包test.helloworld.api; 

公共接口HelloWorld
{
String salute();
}



客户程序



 包test.helloworld.client; 

导入静态java.lang.System.out;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.embeddable.EJBContainer;
import javax.naming.Context;
import javax.transaction.UserTransaction;
import test.helloworld.api.HelloWorld;


公共类HelloWorldEmbeddedEjbTestClient
{
public static void main(String [] args)
{
int status = 1;

试试
{
main();
状态= 0;
}
捕获(可抛出e)
{
e.printStackTrace(System.err);
System.err.flush();
}
最终
{
//简单地从main返回,剩下的线程(还有
//因此是JVM)又运行了60s,所以强制退出
System.exit(status);
}
}


private static void main()引发异常
{
Map< String,Object>属性=新的HashMap< String,Object>();
properties.put(EJBContainer.MODULES,new File [] {new File( ./ HelloWorld-EJB.jar)});;
EJBContainer容器= EJBContainer.createEJBContainer(properties);

试试
{
Context jndiContext = container.getContext();
对象serviceObj = jndiContext.lookup( java:global / HelloWorld-EJB / HelloWorldBean);
out.println( service:\t + serviceObj);
HelloWorld服务=(HelloWorld)serviceObj;
out.println( result:\t + service.salute());

callInTx(service,jndiContext);
}
最终
{
out.println( closing EJBContainer ...);
container.close();
out.println( EJBContainer已关闭。);
}
}


私有静态无效callInTx(HelloWorld service,Context jndiContext)引发异常
{
UserTransaction tx =(UserTransaction) jndiContext.lookup( java:jboss / UserTransaction);
tx.begin();
out.println( tx中的结果:\t + service.salute());
tx.commit();
}
}



包装



C:eclipse\projects\HelloWorldSlSB-Client\rt\HelloWorld-API.jar:

  META-INF / MANIFEST.MF 
test / helloworld / api / HelloWorld.class

C:eclipse\projects\HelloWorldSlSB-Client\rt\HelloWorld-EJB.jar:

  META-INF / MANIFEST.MF 
META-INF / jboss-deployment-structure.xml
test / helloworld / impl / HelloWorldBean.class
test / helloworld / api / HelloWorld.class

HelloWorld-EJB.jar:META-INF / jboss-deployment-structure.xml:

 <?xml version = 1.0 encoding = ISO-8859-1?> 
< jboss-deployment-structure>
< deployment>
< dependencies>< / dependencies>
< exclusions>
< module name = Classpath />
< / exclusions>
< / deployment>
< / jboss-deployment-structure>

C:\eclipse\projects\HelloWorldSlSB-Client\rt\modules\ test\helloworld\client\main\HelloWorldSlSB-Client.jar:

  META-INF / MANIFEST.MF 
test / helloworld / client / HelloWorldEmbeddedEjbTestClient.class

C:\eclipse\projects\ WorldHelloWorldSlSB客户端\rt\模块\测试\Helloworld\客户端\主\module.xml:

 < main-class name = test.helloworld.client.HelloWorldEmbeddedEjbTestClient /> 

<资源>
< resource-root path = HelloWorldSlSB-Client.jar />
< / resources>

<依赖关系>
< module name = javax.api />
< module name = javax.ejb.api />
< module name = org.jboss.as.embedded export = true />
< ;!-
<模块名称= org.jboss.as.server export = true />
->
< / dependencies>
< / module>

所有META-INF / MANIFEST.MF文件只包含 Manifest-Version:1.0。



结果



直接调用



使用 -Xmx512m -XX:MaxPermSize = 256m ,类路径

 <$直接调用HelloWorldEmbeddedEjbTestClient.main c $ c> C:eclipse\output\HelloWorldSlSB-Client 
C:\java\jboss-as-7\jboss-modules.jar
C:\java\ \jboss-as-7\modules\org\jboss\as-embedded\main\jboss-as-embedded-7.1.1.Final.jar
C:\java\ jboss-as-7模块\javax\ejb\api\main\jboss-ejb-api_3.1_spec-1.0.1.Final.jar
C:\java\jboss- as-7组件javax事务API主体jboss-transaction-api_1.1_spec-1.0.0.Final.jar
C:javajboss-as- 7\modules\org\jboss\logging\main\jboss-logging-3.1.0.GA.jar
C:\java\jboss-as-7\modules\ org\jboss\as\controller-client\main\jboss-as-controller-client-7.1.1.Final.jar
C:\java\jboss-as-7\ modules\org\jboss\logmanager\main\jboss-logmanager-1.2.2.GA.jar
C:\java\jboss-as-7\modules\org\ jboss\dmr\m ain\jboss-dmr-1.1.1.Final.jar
C:\eclipse\projects\HelloWorldSlSB-Client\rt\HelloWorld-API.jar

和系统属性

  -Duser。语言= en 
-Djboss.home = c:/ java / jboss-as-7
-Djboss.home.dir = c:/ java / jboss-as-7
-Dorg。 jboss.as.embedded.ejb3.BARREN = true
-Dfile.encoding = ISO-8859-1

EJB调用成功,但是JNDI对象 java:jboss / UserTransaction不能转换为javax.transaction.UserTransaction:

  ... 
19:21:01,875信息[org.jboss.ejb.client](主)JBoss EJB客户端版本1.0.5.Final
服务:远程EJB StatelessEJBLocator {appName的代理='',moduleName ='HelloWorld-EJB',distinctName ='',beanName ='HelloWorldBean',视图='接口test.helloworld.api.HelloWorld'}
结果:您好,世界
正在关闭EJBContainer ...
19:21:06,362信息[org.jboss.as.server.deployment](MSC服务线程1-7)JBAS015877:已停止dep在90毫秒内使用HelloWorld-EJB.jar
19:21:06,370信息[org.jboss.as.repository](pool-9-thread-1)JBAS014901:从位置c:\java\jboss中删除了内容-as-7\独立\数据\内容\35\424415b9a67d64fe8a6dc7ee0700480282f34b\内容
19:21:06,370 INFO [org.jboss.as.server](pool-9-thread-1) JBAS018558:取消部署 HelloWorld-EJB.jar
19:21:06,390 INFO [org.jboss.as.osgi](MSC服务线程1-1)JBAS011942:停止OSGi Framework
EJBContainer已关闭。
java.lang.ClassCastException:org.jboss.tm.usertx.client.ServerVMClientUserTransaction无法转换为javax.transaction.UserTransaction
在test.helloworld.client.HelloWorldEmbeddedEjbTestClient.callInTx(HelloWorldEmbeddedEjbTestClient.java:65 )
在test.helloworld.client.HelloWorldEmbeddedEjbTestClient.main(HelloWorldEmbeddedEjbTestClient.java:52)
在test.helloworld.client.HelloWorldEmbeddedEjbTestClient.main(HelloWorldEmbeddedEjbTestClient.java:21)
c $ c>

(看起来有点奇怪,因为异常是在main的末尾捕获并打印的。但是,当然,它发生在容器之前



调试器显示JNDI对象的getClass()。getClassLoader()是org.jboss.modules.ModuleClassLoader

来自本地模块加载程序@ 4b436982的模块 org.jboss.jboss-transaction-spi:main的ModuleClassLoader(根目录:c:\java\jboss-as-7\modules)

及其getClass()。getInterface s()[0] / * ==接口javax.transaction.UserTransaction * /。getClassLoader()是

来自本地的模块 javax.transaction.api:main的ModuleClassLoader模块加载器@ 4b436982(根:c:\java\jboss-as-7\modules)

但是,UserTransaction.class.getClassLoader()的类型为sun .misc.Launcher $ AppClassLoader。



jboss-modules.jar调用



通过org.jboss.modules调用.Main.main(即带有类路径的 java -jar jboss-modules.jar 也可以做什么

  C:\java\jboss-as-7\jboss-modules.jar 

系统上面的属性和参数

  -mp C:\java\jboss-as-7\modules; C :\eclipse\projects\HelloWorldSlSB-Client\rt\modules 
test.helloworld.client

在createEJBContainer中已经失败:

  javax.ejb.EJBException:无法实例化带有容器的容器[ ] 
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:97)
在test.helloworld.client.HelloWorldEmbeddedEjbTestClient.main(HelloWorldEmbeddedEjbTestClient.java:42)
在测试中。 helloworld.client.HelloWorldEmbeddedEjbTestClient.main(HelloWorldEmbeddedEjbTestClient.java:21)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessor Impl.java:57)sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在java.lang.reflect.Method.invoke(Method.java:601)
在org.jboss.modules.Module.run(Module.java:260)
在org.jboss.modules.Main.main(Main.java:291)

调试表明发生这种情况是因为在方法EJBContainer.findAllFactories()中找不到资源 META-INF / services / javax.ejb.spi.EJBContainerProvider在线程上下文类加载器中,它是本地模块加载器@ 1afec586中的模块 test.helloworld.client:main的
ModuleClassLoader(根目录:C:\java\jboss -as-7\modules,C:eclipse\projects\HelloWorldSlSB-Client\rt\modules)



问题




  • 有人知道如何解决此问题或有任何类似的工作吗?

  • 是正常的JBoss安装是正确的起点,还是我需要特定的可嵌入变体?

  • UserTransaction是否甚至应可在可嵌入场景中使用?

    • 如果是,这是否意味着我也可以将一个XA数据源用于JPA 2 CMT实体和旧式JDBC代码?两者都可以参与同一事务(例如JDBC代码以java.sql.Connection.setAutoCommit(false)开始tx,然后以TransactionAttributeType.REQUIRED调用EJB)?

  • >
  • 有人可以指出我一些文档吗?我发现的只是有关JBoss特定API的较旧资料,而不是标准EJB 3.1方式。

    • 最好是在没有任何测试框架的情况下说明如何使用,因为我正在针对生产用途进行评估。




感谢阅读全部(或部分内容:-)!

解决方案

在记住我已经阅读了 META-INF /服务需要显式导入。因此,客户端的module.xml需要 services = import ,现在看起来像这样:



C: \eclipse\项目\HelloWorldSlSB-Client\rt\modules\test\Helloworld\client\main\module.xml:

 <?xml version = 1.0 encoding = ISO-8859-1?> 
< module xmlns = urn:jboss:module:1.1 name = test.helloworld.client>
< main-class name = test.helloworld.client.HelloWorldEmbeddedEjbTestClient />

<资源>
< resource-root path = HelloWorldSlSB-Client.jar />
< / resources>

<依赖关系>
< module name = javax.api />
< module name = javax.ejb.api />
< module name = org.jboss.as.embedded services = import />
< module name = org.jboss.logmanager />
< module name = test.helloworld />
< / dependencies>
< / module>

此外,一条错误消息告诉我设置系统属性 java.util。 logging.manager org.jboss.logmanager.LogManager ,所以我添加了相应的 -D VM参数。然后出现 ClassNotFoundException:org.jboss.logmanager.LogManager ,所以我在上面添加了logmanager依赖项。



只放 createEJBContainer Map参数中的EJB jar不足以使客户端看到它,因此看来EJB也必须是客户端可以显式依赖的模块(<模块名称= test.helloworld /> )。因此,我将HelloWorld-API.jar和HelloWorld-EJB.jar移至目录 modulePath / test / helloworld / main /(即C:\eclipse\projects\HelloWorldSlSB-Client\rt\) \modules\test\helloworld\main),相应地更改了 new File( ./ HelloWorld-EJB.jar)中的路径,并添加了一个模块。 xml:



C:eclipse\projects\HelloWorldSlSB-Client\rt\modules\test\Helloworld\main\module .xml:

 <?xml version = 1.0 encoding = ISO-8859-1?> 
< module xmlns = urn:jboss:module:1.1 name = test.helloworld>
< resources>
< resource-root path = HelloWorld-API.jar />
< resource-root path = HelloWorld-EJB.jar />
< / resources>
< / module>

我删除了 test / helloworld / api / HelloWorld.class 从EJB jar中。



编辑2013-02-27
找到了一个更简单的工作调用,仍然使用 org.jboss.modules.Main ,但是部署了EJB,因为我们很可能将其用于非嵌入式用途,并且不需要module.xml文件。现在,无参数 createEJBContainer()就足够了,因为我在 -cp 参数中包含了EJB jar。 。



%JBOSS_HOME%\独立\部署包含

  HelloWorld-API.jar 
HelloWorld-EJB.jar

HelloWorld-EJB.jar:

  META-INF / MANIFEST.MF 
META-INF / jboss-deployment-structure.xml
测试/helloworld/impl/HelloWorldBean.class

HelloWorld-EJB.jar:META-INF / jboss-deployment -structure.xml:

 <?xml version = 1.0 encoding = ISO-8859-1?> 
< jboss-deployment-structure>
< deployment>
< dependencies>
< module name = deployment.HelloWorld-API.jar />
< / dependencies>
< exclusions>
< module name = Classpath />
< / exclusions>
< / deployment>
< / jboss-deployment-structure>

调用:

  C:\java\jdk1.7\bin\java -Xmx512m -XX:MaxPermSize = 256m -Duser.language = zh-CN 
-Djboss.home = c:/ java / jboss -as-7 -Djboss.home.dir = c:/ java / jboss-as-7
-Djava.util.logging.manager = org.jboss.logmanager.LogManager
-classpath C: \java\jboss-as-7\jboss-modules.jar
org.jboss.modules.Main
-mp C:\java\jboss-as-7\模块
-dep javax.ejb.api,org.jboss.as.embedded,org.jboss.logmanager
-cp C:eclipse\output\HelloWorldSlSB-Client; C:Java 7个独立的部署,HelloWorld-API.jar; C Java 3个独立的部署,HelloWorld-EJB。 jar
test.helloworld.client.HelloWorldEmbeddedEjbTestClient

目录C:\eclipse\项目\HelloWorldSlSB-客户端\rt\模块:空,不再使用。



编辑结束2013-02-27



剩余问题




  • 如果有人知道s如何在不运行org.jboss.modules.Main的情况下直接调用。我仍然想知道。

  • 仍然非常欢迎文档链接。

  • UserTransaction / JDBC问题



BTW,也许有足够声誉的人可以添加诸如jboss-modules之类的标签? p>

I'm trying out embeddable JBoss with the EJBContainer.createEJBContainer API described in the spec (JSR 318: Enterprise JavaBeans, Version 3.1, ch. 22: Embeddable Usage), not any of the various predecessors using JBoss specific APIs.

Overview

  • When i invoke my main method normally, a session bean invocation succeeds. But there seem to be some classloading issues, because the JNDI object at "java:jboss/UserTransaction" cannot be cast to javax.transaction.UserTransaction.
  • So i guess the classloading magic of JBoss Modules is required here. With my attempts at that, createEJBContainer does not find any EJBContainerProviders and throws an EJBException.

Note that not all my questions require reading all subsequent details. So if this is too much to read, please have a look at the questions section nevertheless. Thanks!

Environment

JBoss AS 7.1.1.Final (jboss-as-7.1.1.Final.zip with only logging conf changed in standalone.xml)
(Initially JBoss EAP 6.0.1 GA which is the actual target environment - same problem)
Oracle JDK 1.7.0_11
Windows 7 Prof 64 bit

Details

The stateless session bean

package test.helloworld.impl;

import javax.ejb.Remote;
import javax.ejb.Stateless;
import test.helloworld.api.HelloWorld;

@Stateless
@Remote(HelloWorld.class)
public class HelloWorldBean implements HelloWorld
{
    @Override
    public String salute()
    {
        return "Hello, world";
    }
}

... and its business interface:

package test.helloworld.api;

public interface HelloWorld
{
    String salute();
}

The client program

package test.helloworld.client;

import static java.lang.System.out;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.embeddable.EJBContainer;
import javax.naming.Context;
import javax.transaction.UserTransaction;
import test.helloworld.api.HelloWorld;


public class HelloWorldEmbeddedEjbTestClient
{
    public static void main(String[] args)
    {
        int status = 1;

        try
        {
            main();
            status = 0;
        }
        catch (Throwable e)
        {
            e.printStackTrace(System.err);
            System.err.flush();
        }
        finally
        {
            // Simply returning from main leaves some thread (and
            // hence the JVM) running for another 60s, so force exit
            System.exit(status);
        }
    }


    private static void main() throws Exception
    {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(EJBContainer.MODULES, new File[]{new File("./HelloWorld-EJB.jar")});
        EJBContainer container = EJBContainer.createEJBContainer(properties);

        try
        {
            Context jndiContext = container.getContext();
            Object serviceObj = jndiContext.lookup("java:global/HelloWorld-EJB/HelloWorldBean");
            out.println("service:\t" + serviceObj);
            HelloWorld service = (HelloWorld) serviceObj;
            out.println("result:\t" + service.salute());

            callInTx(service, jndiContext);
        }
        finally
        {
            out.println("closing EJBContainer...");
            container.close();
            out.println("EJBContainer closed.");
        }
    }


    private static void callInTx(HelloWorld service, Context jndiContext) throws Exception
    {
        UserTransaction tx = (UserTransaction) jndiContext.lookup("java:jboss/UserTransaction");
        tx.begin();
        out.println("result in tx:\t" + service.salute());
        tx.commit();
    }
}

Packaging

C:\eclipse\projects\HelloWorldSlSB-Client\rt\HelloWorld-API.jar:

META-INF/MANIFEST.MF
test/helloworld/api/HelloWorld.class

C:\eclipse\projects\HelloWorldSlSB-Client\rt\HelloWorld-EJB.jar:

META-INF/MANIFEST.MF
META-INF/jboss-deployment-structure.xml
test/helloworld/impl/HelloWorldBean.class
test/helloworld/api/HelloWorld.class

HelloWorld-EJB.jar:META-INF/jboss-deployment-structure.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<jboss-deployment-structure>
    <deployment>
        <dependencies></dependencies>
        <exclusions>
            <module name="Classpath"/>
        </exclusions>
    </deployment>
</jboss-deployment-structure>

C:\eclipse\projects\HelloWorldSlSB-Client\rt\modules\test\helloworld\client\main\HelloWorldSlSB-Client.jar:

META-INF/MANIFEST.MF
test/helloworld/client/HelloWorldEmbeddedEjbTestClient.class

C:\eclipse\projects\HelloWorldSlSB-Client\rt\modules\test\helloworld\client\main\module.xml:

    <main-class name="test.helloworld.client.HelloWorldEmbeddedEjbTestClient"/>

    <resources>
        <resource-root path="HelloWorldSlSB-Client.jar"/>
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="javax.ejb.api"/>
        <module name="org.jboss.as.embedded" export="true"/>
<!--
        <module name="org.jboss.as.server" export="true"/>
-->
    </dependencies>
</module>

All META-INF/MANIFEST.MF files contain nothing but "Manifest-Version: 1.0".

Results

Direct invocation

With a direct invocation of HelloWorldEmbeddedEjbTestClient.main with -Xmx512m -XX:MaxPermSize=256m, classpath

C:\eclipse\output\HelloWorldSlSB-Client
C:\java\jboss-as-7\jboss-modules.jar
C:\java\jboss-as-7\modules\org\jboss\as\embedded\main\jboss-as-embedded-7.1.1.Final.jar
C:\java\jboss-as-7\modules\javax\ejb\api\main\jboss-ejb-api_3.1_spec-1.0.1.Final.jar
C:\java\jboss-as-7\modules\javax\transaction\api\main\jboss-transaction-api_1.1_spec-1.0.0.Final.jar
C:\java\jboss-as-7\modules\org\jboss\logging\main\jboss-logging-3.1.0.GA.jar
C:\java\jboss-as-7\modules\org\jboss\as\controller-client\main\jboss-as-controller-client-7.1.1.Final.jar
C:\java\jboss-as-7\modules\org\jboss\logmanager\main\jboss-logmanager-1.2.2.GA.jar
C:\java\jboss-as-7\modules\org\jboss\dmr\main\jboss-dmr-1.1.1.Final.jar
C:\eclipse\projects\HelloWorldSlSB-Client\rt\HelloWorld-API.jar

and system properties

-Duser.language=en
-Djboss.home=c:/java/jboss-as-7
-Djboss.home.dir=c:/java/jboss-as-7
-Dorg.jboss.as.embedded.ejb3.BARREN=true
-Dfile.encoding=ISO-8859-1

the EJB invocation succeeds, but JNDI object "java:jboss/UserTransaction" cannot be cast to javax.transaction.UserTransaction:

...
19:21:01,875 INFO  [org.jboss.ejb.client] (main) JBoss EJB Client version 1.0.5.Final
service:    Proxy for remote EJB StatelessEJBLocator{appName='', moduleName='HelloWorld-EJB', distinctName='', beanName='HelloWorldBean', view='interface test.helloworld.api.HelloWorld'}
result: Hello, world
closing EJBContainer...
19:21:06,362 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-7) JBAS015877: Stopped deployment HelloWorld-EJB.jar in 90ms
19:21:06,370 INFO  [org.jboss.as.repository] (pool-9-thread-1) JBAS014901: Content removed from location c:\java\jboss-as-7\standalone\data\content\35\424415b9a67d64fe8a6dc7ee0700480282f34b\content
19:21:06,370 INFO  [org.jboss.as.server] (pool-9-thread-1) JBAS018558: Undeployed "HelloWorld-EJB.jar"
19:21:06,390 INFO  [org.jboss.as.osgi] (MSC service thread 1-1) JBAS011942: Stopping OSGi Framework
EJBContainer closed.
java.lang.ClassCastException: org.jboss.tm.usertx.client.ServerVMClientUserTransaction cannot be cast to javax.transaction.UserTransaction
    at test.helloworld.client.HelloWorldEmbeddedEjbTestClient.callInTx(HelloWorldEmbeddedEjbTestClient.java:65)
    at test.helloworld.client.HelloWorldEmbeddedEjbTestClient.main(HelloWorldEmbeddedEjbTestClient.java:52)
    at test.helloworld.client.HelloWorldEmbeddedEjbTestClient.main(HelloWorldEmbeddedEjbTestClient.java:21)

(Looks a little strange, because the exception is caught and printed at the end of main. But of course, it happens before the container is closed.)

The debugger shows that the JNDI object's getClass().getClassLoader() is org.jboss.modules.ModuleClassLoader
ModuleClassLoader for Module "org.jboss.jboss-transaction-spi:main" from local module loader @4b436982 (roots: c:\java\jboss-as-7\modules)
and its getClass().getInterfaces()[0] /* == interface javax.transaction.UserTransaction */.getClassLoader() is
ModuleClassLoader for Module "javax.transaction.api:main" from local module loader @4b436982 (roots: c:\java\jboss-as-7\modules)
However, UserTransaction.class.getClassLoader() is of type sun.misc.Launcher$AppClassLoader.

jboss-modules.jar invocation

Invoked via org.jboss.modules.Main.main (i.e. what java -jar jboss-modules.jar also does) with classpath

C:\java\jboss-as-7\jboss-modules.jar

system properties as above, and arguments

-mp "C:\java\jboss-as-7\modules;C:\eclipse\projects\HelloWorldSlSB-Client\rt\modules"
test.helloworld.client

it fails already in createEJBContainer:

javax.ejb.EJBException: Unable to instantiate container with factories []
    at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:97)
    at test.helloworld.client.HelloWorldEmbeddedEjbTestClient.main(HelloWorldEmbeddedEjbTestClient.java:42)
    at test.helloworld.client.HelloWorldEmbeddedEjbTestClient.main(HelloWorldEmbeddedEjbTestClient.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.jboss.modules.Module.run(Module.java:260)
    at org.jboss.modules.Main.main(Main.java:291)

Debugging shows that this happens because in method EJBContainer.findAllFactories(), no resources "META-INF/services/javax.ejb.spi.EJBContainerProvider" are found in the thread context classloader, which is
ModuleClassLoader for Module "test.helloworld.client:main" from local module loader @1afec586 (roots: C:\java\jboss-as-7\modules,C:\eclipse\projects\HelloWorldSlSB-Client\rt\modules)

Questions

  • Does anyone know how to fix this or has gotten anything similar to work?
  • Is a normal JBoss installation the right starting point, or do i need a specific embeddable variant?
  • Is UserTransaction even supposed to be usable in the embeddable scenario?
    • If it is, does that mean i could also use one XA datasource for both JPA 2 CMT entities and legacy JDBC code? And both could participate in the same transaction (e.g. JDBC code starts tx with java.sql.Connection.setAutoCommit(false), then calls EJB with TransactionAttributeType.REQUIRED)?
  • Can someone point me to some documentation? All i find is about the older stuff with JBoss specific API, not the standard EJB 3.1 way.
    • Preferably, documentation how to use without any test frameworks, since i'm evaluating this for production use.

Thanks for reading all (or part of :-) this!

解决方案

I found the solution for the JBoss Modules way, after remembering that i had read that META-INF/services need to be imported explicitly. So, the client's module.xml needs a services="import" and now looks like this:

C:\eclipse\projects\HelloWorldSlSB-Client\rt\modules\test\helloworld\client\main\module.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<module xmlns="urn:jboss:module:1.1" name="test.helloworld.client">
    <main-class name="test.helloworld.client.HelloWorldEmbeddedEjbTestClient"/>

    <resources>
        <resource-root path="HelloWorldSlSB-Client.jar"/>
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="javax.ejb.api"/>
        <module name="org.jboss.as.embedded" services="import"/>
        <module name="org.jboss.logmanager"/>
        <module name="test.helloworld"/>
    </dependencies>
</module>

Besides, an error message told me to set system property java.util.logging.manager to org.jboss.logmanager.LogManager, so i added a corresponding -D VM argument. Then came ClassNotFoundException: org.jboss.logmanager.LogManager, so i added the logmanager dependency above.

Only putting the EJB jar into the createEJBContainer Map argument was not sufficient for the client to see it, so it seems the EJB must also be a module which the client can explicitely depend on (<module name="test.helloworld"/> above). So i moved HelloWorld-API.jar and HelloWorld-EJB.jar to directory modulePath/test/helloworld/main/ (i.e. C:\eclipse\projects\HelloWorldSlSB-Client\rt\modules\test\helloworld\main), changed the path in new File("./HelloWorld-EJB.jar") accordingly, and added a module.xml for them:

C:\eclipse\projects\HelloWorldSlSB-Client\rt\modules\test\helloworld\main\module.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<module xmlns="urn:jboss:module:1.1" name="test.helloworld">
    <resources>
        <resource-root path="HelloWorld-API.jar"/>
        <resource-root path="HelloWorld-EJB.jar"/>
    </resources>
</module>

I removed test/helloworld/api/HelloWorld.class from the EJB jar. Not necessary, but maybe cleaner.

Edit 2013-02-27: Found a simpler working invocation, still using org.jboss.modules.Main, but with the EJB deployed as we'll probably do for the non-embedded use and no module.xml files required. And the no-arg createEJBContainer() is now sufficient, as i included the EJB jar in the -cp argument instead.

%JBOSS_HOME%\standalone\deployments contains

HelloWorld-API.jar
HelloWorld-EJB.jar

HelloWorld-EJB.jar:

META-INF/MANIFEST.MF
META-INF/jboss-deployment-structure.xml
test/helloworld/impl/HelloWorldBean.class

HelloWorld-EJB.jar:META-INF/jboss-deployment-structure.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<jboss-deployment-structure>
    <deployment>
        <dependencies>
            <module name="deployment.HelloWorld-API.jar"/>
        </dependencies>
        <exclusions>
            <module name="Classpath"/>
        </exclusions>
    </deployment>
</jboss-deployment-structure>

Invocation:

C:\java\jdk1.7\bin\java -Xmx512m -XX:MaxPermSize=256m -Duser.language=en
-Djboss.home=c:/java/jboss-as-7 -Djboss.home.dir=c:/java/jboss-as-7
-Djava.util.logging.manager=org.jboss.logmanager.LogManager
-classpath "C:\java\jboss-as-7\jboss-modules.jar"
org.jboss.modules.Main
-mp "C:\java\jboss-as-7\modules"
-dep "javax.ejb.api, org.jboss.as.embedded, org.jboss.logmanager"
-cp "C:\eclipse\output\HelloWorldSlSB-Client;C:\java\jboss-as-7\standalone\deployments\HelloWorld-API.jar;C:\java\jboss-as-7\standalone\deployments\HelloWorld-EJB.jar"
test.helloworld.client.HelloWorldEmbeddedEjbTestClient

Directory C:\eclipse\projects\HelloWorldSlSB-Client\rt\modules: empty, no longer used.

End of edit 2013-02-27

Remaining questions

  • If someone knows how to get the direct invocation without org.jboss.modules.Main running, i'd still like to know.
  • Documentation links are still very welcome.
  • The UserTransaction / JDBC question

BTW, maybe someone with enough reputation could add a tag like jboss-modules?

这篇关于嵌入式JBoss EAP 6 / AS 7入门的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆