更新时间:2023-12-03 13:50:04
在记住我已经阅读了 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
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.
"java:jboss/UserTransaction"
cannot be cast to javax.transaction.UserTransaction.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!
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
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();
}
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();
}
}
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".
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.ModuleClassLoaderModuleClassLoader 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() isModuleClassLoader 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.
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 isModuleClassLoader 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)
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
BTW, maybe someone with enough reputation could add a tag like jboss-modules?