我在EJB3.1中有EJB,我试图在JBoss EAP 6中部署它,但当我启动服务器时。它在JNDI名称中附加版本号,如下所示。
18:27:57,068 INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-6) JNDI bindings for session bean named TestService in deployment unit subdeployment "TestGroup-war-3_0_0-SNAPSHOT.war" of deployment "TestGroup-ear-3_0_0-SNAPSHOT.ear" are as follows:
java:global/TestGroup-ear-3_0_0-SNAPSHOT/TestGroup-war-3_0_0-SNAPSHOT/TestService!org.pkg.ejb.local.CRMDataServiceLocal
java:app/TestGroup-war-3_0_0-SNAPSHOT/TestService!org.pkg.ejb.local.CRMDataServiceLocal
java:module/TestService!org.pkg.ejb.local.CRMDataServiceLocal
java:global/TestGroup-ear-3_0_0-SNAPSHOT/TestGroup-war-3_0_0-SNAPSHOT/TestService
java:app/TestGroup-war-3_0_0-SNAPSHOT/TestService
java:module/TestService
如何从JNDI名称中删除版本号“-3_0_0-SNAPSHOT”?我有ejb jar。部署ear时放在ejbjar文件中的xml。
您不必删除版本信息。您可以通过JNDI自助获取正确的应用程序和模块名称!请参见这里的答案:https://stackoverflow.com/a/7066600/1465758
如果您已经在EJB容器中,您可以使用< code>@Resource注释:
@Resource(lookup = "java:app/AppName")
private String appName;
@Resource(lookup = "java:module/ModuleName")
private String moduleName;
如果您在EJB容器之外,则必须使用JNDI查找,如:
Context jndiCtxt = new InitialContext();
String appName = (String) jndiCtxt.lookup("java:app/AppName");
String moduleName = (String) jndiCtxt.lookup("java:module/ModuleName");
然后,您可以通过以下方式访问您的测试服务:
Context jndiCtxt = new InitialContext();
TestService testSvc = (TestService) jndiCtxt.lookup(
"java:global/" + appName + "/" + moduleName + "/TestService");
编辑:
如果您有多个作为一个模块的模块,那么在java:module/ModuleName上的JNDI查找可能会返回错误的模块名称。您还可以通过调用
NamingEnumeration<NameClassPair> list =
jndiCtxt.list("java:global/" + appName + "/");
或者更好:在启动应用程序时,可以在静态映射中加载所有已知的实体/类和相应的JNDI URI。例如:
public final class EJBUtil<T> {
private static final Logger log = PSLogger.getLogger(EJBUtil.class);
/** list of all known JNDI entities sort by the class: {Class; JNDI URI} */
private final static Map<Class<?>, String> jndiEntities = new HashMap<>();
/** synchronisation object for filling jndiEntities */
private final static ReentrantLock jndiEntitiesLock = new ReentrantLock();
/** the initial context */
private static Context jndiCtxt = null;
/**
* class of the bean to get
*/
private final Class<T> beanClass;
/**
* Constructs a new EJBUtil for the specified simple bean class name.
* @param beanClass bean class for which this EJBUtil is
*/
public EJBUtil(Class<T> beanClass) {
this.beanClass = beanClass;
}
/**
* Creates and returns a bean object from the EJB container.
* @return the bean instance or null
*/
@SuppressWarnings("unchecked")
public final T getBean() {
String jndiURI = null;
try {
if (jndiEntities.isEmpty()) {
try {
loadEntityMap();
} catch (NamingException exc) {
exc.printStackTrace();
log.error(null, "! ! ! ! ! C A N N O T L O A D T H E J N D I E N T I T I E S ! ! ! ! !",
exc);
return null;
}
}
jndiURI = jndiEntities.get(beanClass);
if (jndiURI == null) {
log.error(null, "! ! ! ! ! C A N N O T L O A D T H E \"" + beanClass.getSimpleName()
+ "\" B E A N (Entity not found in Naming Directory ! ! ! ! !");
return null;
}
Object obj = jndiLookup(jndiURI);
return (T) obj;
} catch (NamingException exc) {
exc.printStackTrace();
log.error(null, "! ! ! ! ! C A N N O T L O A D T H E \"" + beanClass.getSimpleName()
+ "\" B E A N (JNDI URI: \"" + jndiURI + "\") ! ! ! ! !",
exc);
return null;
}
}
/**
* Creates and returns a bean object from the EJB container.
* @param name JNDI name of the resource to return
* @return the resource object or null
* @throws NamingException if the bean could not be created
*/
public static final Object jndiLookup(String name) throws NamingException {
try {
if (jndiCtxt == null) {
jndiCtxt = new InitialContext();
}
return jndiCtxt.lookup(name);
} catch (NamingException exc) {
exc.printStackTrace();
log.error(null, "! ! ! ! ! C A N N O T L O A D T H E J N D I R E S O U R C E \"" + name +
"\" (JNDI: \"" + name + "\") ! ! ! ! !", exc);
throw exc;
}
}
private void loadEntityMap() throws NamingException {
jndiEntitiesLock.lock();
try {
if (!jndiEntities.isEmpty()) {
// map already filled
return;
}
loadEntityMap("java:global/");
} finally {
jndiEntitiesLock.unlock();
}
}
private void loadEntityMap(String jndiBaseURI) throws NamingException {
if (jndiCtxt == null) {
jndiCtxt = new InitialContext();
}
NamingEnumeration<NameClassPair> list = jndiCtxt.list(jndiBaseURI);
while (list.hasMore()) {
NameClassPair nameClassPair = list.next();
if (nameClassPair.getClassName() != null &&
!nameClassPair.getClassName().equals(Context.class.getName())) {
try {
jndiEntities.put(
Class.forName(nameClassPair.getClassName()), jndiBaseURI + "/" + nameClassPair.getName());
} catch (ClassNotFoundException e) {
log.error(null, "Cannot load JNDI entity class " + nameClassPair.getClassName(), e);
}
}
if (nameClassPair.getClassName() == null ||
nameClassPair.getClassName().equals(Context.class.getName())) {
loadEntityMap(jndiBaseURI + nameClassPair.getName() + "/");
}
}
}
}
然后可以通过调用以下命令加载EJB测试服务:
TestService testSvc = new EJBUtil<TestService>(TestService.class).getBean();
上面的答案对我不起作用。在我的例子中,我将maven-ear-plugin升级到了版本2.10,并提供了“文件名映射”属性作为“无版本”:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10</version>
<configuration>
<!-- Tell Maven we are using Java EE 7 -->
<version>7</version>
<fileNameMapping>no-version</fileNameMapping>
<generateApplicationXml>true</generateApplicationXml>
<defaultLibBundleDir>/lib</defaultLibBundleDir>
<modules>
<ejbModule>
<groupId>${project.groupId}</groupId>
<artifactId>dpc-ejb</artifactId>
<bundleDir>/</bundleDir>
</ejbModule>
<webModule>
<groupId>${project.groupId}</groupId>
<artifactId>dpc-war</artifactId>
<bundleDir>/</bundleDir>
<contextRoot>dpc</contextRoot>
</webModule>
</modules>
</configuration>
</plugin>
根据EJB JNDI命名参考,会话bean的JNDI查找名称具有以下语法:
ejb:<appName>/<moduleName>/<distinctName>/<beanName>!<viewClassName>?stateful
因此,你想要的可以通过两种方式实现:
为了从WAR中删除该版本,您可以在WAR的POM中执行以下操作:
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
</build>
关于您的EAR,为了从中删除版本,您可以将以下内容放在EAR的POM中:
<build>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
(...)
<finalName>${project.artifactId}</finalName>
(...)
</configuration>
</plugin>
</plugins>
</build>
使用上面的配置,您将拥有如下内容:
.../TestGroup-ear/TestGroup-war/...
创建一个包含以下内容的 ejb-jar.xml,并将其放在 WAR 的 src/主/网络应用/WEB-INF 文件夹下:
<ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd"
version="3.2">
<module-name>someModuleName</module-name>
</ejb-jar>
然后,在EAR的src/main/resources/META-INF文件夹下放置一个application.xml文件,其内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/application_7.xsd"
version="7">
<application-name>someApplicationName</application-name>
</<module>
<web>
<web-uri>TestGroup-war-${project.version}.war</web-uri>
<context-root>testGroup</context-root>
</web>
</module>
</application>
然后,在您的 JNDI 上,您将获得如下内容:
java:global/someApplicationName/someModuleName/TestService!org.pkg.ejb.local.CRMDataServiceLocal
java:app/someModuleName/TestService!org.pkg.ejb.local.CRMDataServiceLocal
java:module/TestService!org.pkg.ejb.local.CRMDataServiceLocal
java:global/someApplicationName/someModuleName/TestService
java:app/someModuleName/TestService
java:module/TestService
从2.5版开始,Maven EAR插件具有选项no-version
,可以设置为属性fileNameMap
,以便从您的工件中省略该版本:
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
(...)
<fileNameMapping>no-version</fileNameMapping>
(...)
</configuration>
</plugin>
我试图在JBoss7上运行这个EJB示例,但它总是抛出NameNotFoundException。 我尝试测试的EJB是:计算器。在JBoss 7上部署时,在服务器控制台中显示以下几行: 计算器bean代码如下所示: 远程接口代码为: 必须通过JNDI连接EJB的主代码是: 第一个错误是:身份验证失败。因此,我在服务器:usr: test,pwd: test123中创建了一个用于“应用领域”的“管
当我将mvn项目导入Intellij时,它生成的jar文件不包括版本。但是mvn生成的jar具有格式。所以我最终得到了两个jar文件,一个有版本,另一个没有版本。当然,我可以在Intellij设置中更改模块名称以包括版本。但当我更改pom文件时,它将被重置。 也许其他人有更好的主意?
我有一个遗留的 EJB 2 应用程序,我将其部署到 Websphere 8.5 中。该应用程序具有依赖关系,这些依赖关系定义了与数据源的 JNDI 绑定.xml和 /元.xml数据源.xml 我不允许更改这些依赖项中的代码,也不能更改Websphere的配置。但我可以更改jar文件中的配置文件。 我想在我的应用程序中覆盖有效的JNDI绑定。是否可以定义一个将添加到Ear的文件来覆盖这些绑定? ej
我的Web应用程序包含几个2. x有状态和无状态会话ejbs.但与以前的jboss版本(以及其他主要的应用程序服务器)不同,我无法在jboss 7.1.1中指定ejb jndi名称。/>有利于jboss-ejb3.xml,以及在完整配置文件模式下启动应用服务器。 然而,jboss-ejb3.xml中的jndi-name没有站稳脚跟,阻止我设置自己的自定义ejb jndi名称。
我正在JBoss7.1上部署一个JavaEE应用程序。1,当部署会话bean时,JBoss会打印一条消息,说明它已经创建了多个JNDI绑定。大概是这样的: EJB和EJB之间有一点不同,但这是一般的想法。 我对这里发生的事情感到困惑。为什么有这么多?这些JNDI绑定之间有区别吗?如果有,应该在什么时候使用它们?
我编写了这样的代码来查找Android版本 通过使用这段代码,我得到的是版本号,但我想要的是版本名。如何获取版本名?