从 bean 中找出全局 jndi 名称
Find out global jndi name from within bean
我在 JBoss 7.4 中部署了多个 JavaEE6 应用程序 (.war)。
所有这些应用程序都包含一个提供 Singleton-Bean 实现的公共库。
使用 JBoss 模块文件夹为每个应用程序配置不同的单例 bean,并且应该记录一些特定于应用程序的信息 - 这已经可以正常工作了。
但是我很难区分哪个日志行来自哪个应用程序。
当服务器为每个应用程序(my-app1、my-app2、...)启动时,我在日志中有以下输出:
INFO 10:45:54,998 (EjbJndiBindingsDeploymentUnitProcessor.java:setupJNDIBindings:183) -JNDI bindings for session bean named MyBean in deployment unit deployment "my-app1.war" are as follows:
java:global/my-app1/MyBean!my.package.MyBean
java:app/my-app1/MyBean!my.package.MyBean
java:module/MyBean!my.package.MyBean
java:global/my-app1/MyBean
java:app/my-app1/MyBean
java:module/MyBean
这个输出正是我所需要的,所以我想检索在我的代码中部署 MyBean 的全局 jndi 名称:
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import org.apache.log4j.Logger;
@Singleton
@Startup
public class MyBean {
private static final Logger log = Logger.getLogger(MyBean.class);
@PostConstruct
private void postConstruct() {
String appName = ""; // .getGlobalJndiNameOfThisInstance();
log.info("MyBean available for application " + appName);
// and log further application specific info
}
}
在研究这个时,我只找到了大量关于如何通过 jndi 查找 bean 的信息,我不需要这些信息。我可以通过创建 new InitialContext()
以某种方式提取应用程序名称吗?
我找到了查找名称的方法。它可以通过名称 java:app/AppName
或 java:module/ModuleName
.
下的 jndi-lookup 获得
我按如下方式扩展了我的 EJB:
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import org.apache.log4j.Logger;
@Singleton
@Startup
public class MyBean {
@Resource(lookup = "java:app/AppName")
String appName;
private static final Logger log = Logger.getLogger(MyBean.class);
@PostConstruct
private void postConstruct() {
log.info("MyBean available for application " + appName);
// and log further application specific info
}
}
import java.net.URL;
import java.util.*;
import javax.ejb.Stateless;
import javax.naming.*;
import net.sf.extcos.ComponentQuery;
import net.sf.extcos.ComponentScanner;
public class ServiceLocator {
public <T extends Object> T lookup(Class<T> interfaceLocal) {
try {
return (T) getInitialContext().lookup(buildJNDIWildfly(interfaceLocal));
} catch (NamingException e) {
throw new RuntimeException(e);
}
}
public <T> String buildJNDIWildfly(final Class<T> interfaceLocal) {
Class<? extends T> clazz = getImplementorOf(interfaceLocal, getPackagesToScan());
if (clazz != null) {
URL url = getUrlOfClass(clazz);
String module = getModuleName(url);
return "global/" + module + "/" + clazz.getSimpleName() + "!" + interfaceLocal.getName();
}
return null;
}
public String[] getPackagesToScan() {
// important to reduce range of search
return new String[] { "my.package.of.ejbs" };
}
public static URL getUrlOfClass(Class<?> clazz) {
if (clazz == null) {
throw new NullPointerException();
}
String resourceName = clazz.getName().replace('.', '/') + ".class";
ClassLoader classLoader = clazz.getClassLoader();
if (classLoader == null) {
classLoader = ClassLoader.getSystemClassLoader();
}
return classLoader.getResource(resourceName);
}
public <T> Class<? extends T> getImplementorOf(final Class<T> interfaceLocal, final String... packagesToScan) {
// https://sourceforge.net/projects/extcos
final Set<Class<?>> classes = new HashSet<Class<?>>();
ComponentScanner scanner = new ComponentScanner();
scanner.getClasses(new ComponentQuery() {
@Override
protected void query() {
select().from(packagesToScan).andStore(
thoseBeing(and(annotatedWith(Stateless.class), implementorOf(interfaceLocal))).into(classes))
.returning(none());
}
});
if (classes.size() > 0) {
return (Class<? extends T>) classes.iterator().next();
} else {
return null;
}
}
private String getModuleName(URL urlOfClass) {
if (urlOfClass != null) {
// Ex:
// vfs:/opt/jboss-eap-6.4/standalone/deployments/myEar.ear/my-module.jar/my/interface/local/MyInterface.class
String filePath = urlOfClass.getFile();
int earPosition = filePath.lastIndexOf(".ear");
int jarPosition = filePath.lastIndexOf(".jar");
String earName = null;
String moduleName = null;
if (earPosition >= 0) {
earName = filePath.substring(filePath.lastIndexOf('/', earPosition) + 1, earPosition);
}
if (jarPosition >= 0) {
moduleName = filePath.substring(filePath.lastIndexOf('/', jarPosition) + 1, jarPosition);
if (earName != null) {
moduleName = earName + "/" + moduleName;
}
}
return moduleName;
}
return null;
}
private InitialContext getInitialContext() {
try {
Hashtable<String, String> props = new Hashtable<String, String>();
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
return new InitialContext(props);
} catch (NamingException e) {
throw new RuntimeException(e);
}
}
}
我在 JBoss 7.4 中部署了多个 JavaEE6 应用程序 (.war)。 所有这些应用程序都包含一个提供 Singleton-Bean 实现的公共库。 使用 JBoss 模块文件夹为每个应用程序配置不同的单例 bean,并且应该记录一些特定于应用程序的信息 - 这已经可以正常工作了。
但是我很难区分哪个日志行来自哪个应用程序。
当服务器为每个应用程序(my-app1、my-app2、...)启动时,我在日志中有以下输出:
INFO 10:45:54,998 (EjbJndiBindingsDeploymentUnitProcessor.java:setupJNDIBindings:183) -JNDI bindings for session bean named MyBean in deployment unit deployment "my-app1.war" are as follows:
java:global/my-app1/MyBean!my.package.MyBean
java:app/my-app1/MyBean!my.package.MyBean
java:module/MyBean!my.package.MyBean
java:global/my-app1/MyBean
java:app/my-app1/MyBean
java:module/MyBean
这个输出正是我所需要的,所以我想检索在我的代码中部署 MyBean 的全局 jndi 名称:
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import org.apache.log4j.Logger;
@Singleton
@Startup
public class MyBean {
private static final Logger log = Logger.getLogger(MyBean.class);
@PostConstruct
private void postConstruct() {
String appName = ""; // .getGlobalJndiNameOfThisInstance();
log.info("MyBean available for application " + appName);
// and log further application specific info
}
}
在研究这个时,我只找到了大量关于如何通过 jndi 查找 bean 的信息,我不需要这些信息。我可以通过创建 new InitialContext()
以某种方式提取应用程序名称吗?
我找到了查找名称的方法。它可以通过名称 java:app/AppName
或 java:module/ModuleName
.
我按如下方式扩展了我的 EJB:
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import org.apache.log4j.Logger;
@Singleton
@Startup
public class MyBean {
@Resource(lookup = "java:app/AppName")
String appName;
private static final Logger log = Logger.getLogger(MyBean.class);
@PostConstruct
private void postConstruct() {
log.info("MyBean available for application " + appName);
// and log further application specific info
}
}
import java.net.URL;
import java.util.*;
import javax.ejb.Stateless;
import javax.naming.*;
import net.sf.extcos.ComponentQuery;
import net.sf.extcos.ComponentScanner;
public class ServiceLocator {
public <T extends Object> T lookup(Class<T> interfaceLocal) {
try {
return (T) getInitialContext().lookup(buildJNDIWildfly(interfaceLocal));
} catch (NamingException e) {
throw new RuntimeException(e);
}
}
public <T> String buildJNDIWildfly(final Class<T> interfaceLocal) {
Class<? extends T> clazz = getImplementorOf(interfaceLocal, getPackagesToScan());
if (clazz != null) {
URL url = getUrlOfClass(clazz);
String module = getModuleName(url);
return "global/" + module + "/" + clazz.getSimpleName() + "!" + interfaceLocal.getName();
}
return null;
}
public String[] getPackagesToScan() {
// important to reduce range of search
return new String[] { "my.package.of.ejbs" };
}
public static URL getUrlOfClass(Class<?> clazz) {
if (clazz == null) {
throw new NullPointerException();
}
String resourceName = clazz.getName().replace('.', '/') + ".class";
ClassLoader classLoader = clazz.getClassLoader();
if (classLoader == null) {
classLoader = ClassLoader.getSystemClassLoader();
}
return classLoader.getResource(resourceName);
}
public <T> Class<? extends T> getImplementorOf(final Class<T> interfaceLocal, final String... packagesToScan) {
// https://sourceforge.net/projects/extcos
final Set<Class<?>> classes = new HashSet<Class<?>>();
ComponentScanner scanner = new ComponentScanner();
scanner.getClasses(new ComponentQuery() {
@Override
protected void query() {
select().from(packagesToScan).andStore(
thoseBeing(and(annotatedWith(Stateless.class), implementorOf(interfaceLocal))).into(classes))
.returning(none());
}
});
if (classes.size() > 0) {
return (Class<? extends T>) classes.iterator().next();
} else {
return null;
}
}
private String getModuleName(URL urlOfClass) {
if (urlOfClass != null) {
// Ex:
// vfs:/opt/jboss-eap-6.4/standalone/deployments/myEar.ear/my-module.jar/my/interface/local/MyInterface.class
String filePath = urlOfClass.getFile();
int earPosition = filePath.lastIndexOf(".ear");
int jarPosition = filePath.lastIndexOf(".jar");
String earName = null;
String moduleName = null;
if (earPosition >= 0) {
earName = filePath.substring(filePath.lastIndexOf('/', earPosition) + 1, earPosition);
}
if (jarPosition >= 0) {
moduleName = filePath.substring(filePath.lastIndexOf('/', jarPosition) + 1, jarPosition);
if (earName != null) {
moduleName = earName + "/" + moduleName;
}
}
return moduleName;
}
return null;
}
private InitialContext getInitialContext() {
try {
Hashtable<String, String> props = new Hashtable<String, String>();
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
return new InitialContext(props);
} catch (NamingException e) {
throw new RuntimeException(e);
}
}
}