在 Tomcat 8 中如何使用全局 JNDI URL 资源?
How do you use global JNDI URL resources in Tomcat 8?
我正在尝试设置服务器 运行 Tomcat 8 以使该服务器上的大量应用程序 运行 可以使用 JNDI URL 资源。这些应用程序是普通的 jsp/servlet Maven(没有 Spring)。
我有 2 个我正在尝试使用的全局资源示例,一个是正常工作的数据源,一个是 URL 没有。
数据源
在 Tomcats context.xml 内的 GlobalNamingResources 元素
<Resource name="APPNAME" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="appuser"
password="password" driverClassName="oracle.jdbc.driver.OracleDriver"
url="aUrl" />
在 Tomcats web.xml 中,顶级元素
<resource-ref>
<res-ref-name>APPNAME</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
DataSource 就是这些,它确实有效
对于 URL 资源,我在 server.xml
中有这个
<Resource name="url/LOGIN_MODULE_CONFIGURATION_SERVICE" auth="Container"
type="java.net.URL" factory="com.mycompany.objectfactory.JndiUrlObjectFactory"
url="AValidUrl" />
我的对象工厂的创建方式与此答案相同:Tomcat: use FTP connection via JNDI 除了我添加了一些 println 语句以证明它正在被使用并且具有正确的 url 。
我有以下 Tomcats web.xml
<resource-ref>
<res-ref-name>url/LOGIN_MODULE_CONFIGURATION_SERVICE</res-ref-name>
<res-type>java.net.URL</res-type>
<res-auth>Container</res-auth>
</resource-ref>
最后访问这个的代码。这段代码是反编译一个jar的结果,它不是第三方jar,但我没有源代码。异常发生在 jndiReference = ic.lookup(serviceName);
行。 serviceName
为资源名称,jndiRoot
始终为null(调用该方法的代码传入null)。 getInitialContext()
方法只是创建一个 javax.naming.InitialContext
的新实例(如果尚未创建的话)。
public static URL getUrl(final String serviceName, final String jndiRoot) {
URL result = null;
if (!isEmpty((Object) serviceName)) {
final InitialContext ic = getInitialContext();
Object jndiReference = null;
try {
jndiReference = ic.lookup(serviceName);
} catch (NamingException ex) {
ex.printStackTrace();
if (!isEmpty((Object) jndiRoot)) {
final String name = String.valueOf(jndiRoot) + serviceName;
try {
jndiReference = ic.lookup(name);
} catch (NamingException ex2) {
ex.printStackTrace();
}
}
}
if (jndiReference instanceof URL) {
result = (URL) jndiReference;
} else if (jndiReference instanceof Reference) {
final Reference reference = (Reference) jndiReference;
final RefAddr refAddr = reference.get("spec");
try {
result = new URL(getString(refAddr.getContent()));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
return result;
}
属性文件中映射到资源的行 propertyserviceurl=url/LOGIN_MODULE_CONFIGURATION_SERVICE
我也曾尝试将 ResourceLink 添加到 Tomcats context.xml。我试过使 ResourceLink 的名称唯一,并且 global 的值与实际资源相同。还尝试修改 属性 文件以映射到 ResourceLink 名称而不是 Resource 但我总是得到相同的结果。
<ResourceLink name="url/LOGIN_MODULE_CONFIGURATION_SERVICE"
global="url/LOGIN_MODULE_CONFIGURATION_SERVICE" type="java.net.URL" />
异常
javax.naming.NameNotFoundException: Name [url/LOGIN_MODULE_CONFIGURATION_SERVICE] is not bound in this Context. Unable to find [url].
at org.apache.naming.NamingContext.lookup(NamingContext.java:816)
at org.apache.naming.NamingContext.lookup(NamingContext.java:173)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:163)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.mycompany.common.supplement.web.WebHelper.getUrl(WebHelper.java:739)
我在这上面花了几天时间,但我无法弄清楚我需要什么配置才能让它工作。我认为最大的障碍是我无法更改尝试访问资源的 java 代码。
我让它工作了。我真的不明白 ResourceLink 是如何工作的,因为它的名称在任何地方都没有被引用。但是,如果有任何不同,它将不起作用。基本上我需要将 java:/comp/env/
添加到资源名称的开头,因为我无法更新调用它的代码。
已将 Tomcats 中的资源 server.xml 更新为
<Resource name="java:/comp/env/url/LOGIN_MODULE_CONFIGURATION_SERVICE" auth="Container"
type="java.net.URL" factory="com.mycompany.objectfactory.JndiUrlObjectFactory"
url="AValidUrl" />
已将 Tomcats context.xml 中的 ResourceLink 更新为
<ResourceLink name="url/LOGIN_MODULE_CONFIGURATION_SERVICE"
global="java:/comp/env/url/LOGIN_MODULE_CONFIGURATION_SERVICE" type="java.net.URL" />
将属性文件条目更新为
propertyserviceurl=java:/comp/env/url/LOGIN_MODULE_CONFIGURATION_SERVICE
我正在尝试设置服务器 运行 Tomcat 8 以使该服务器上的大量应用程序 运行 可以使用 JNDI URL 资源。这些应用程序是普通的 jsp/servlet Maven(没有 Spring)。
我有 2 个我正在尝试使用的全局资源示例,一个是正常工作的数据源,一个是 URL 没有。
数据源
在 Tomcats context.xml 内的 GlobalNamingResources 元素
<Resource name="APPNAME" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="appuser"
password="password" driverClassName="oracle.jdbc.driver.OracleDriver"
url="aUrl" />
在 Tomcats web.xml 中,顶级元素
<resource-ref>
<res-ref-name>APPNAME</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
DataSource 就是这些,它确实有效
对于 URL 资源,我在 server.xml
中有这个<Resource name="url/LOGIN_MODULE_CONFIGURATION_SERVICE" auth="Container"
type="java.net.URL" factory="com.mycompany.objectfactory.JndiUrlObjectFactory"
url="AValidUrl" />
我的对象工厂的创建方式与此答案相同:Tomcat: use FTP connection via JNDI 除了我添加了一些 println 语句以证明它正在被使用并且具有正确的 url 。
我有以下 Tomcats web.xml
<resource-ref>
<res-ref-name>url/LOGIN_MODULE_CONFIGURATION_SERVICE</res-ref-name>
<res-type>java.net.URL</res-type>
<res-auth>Container</res-auth>
</resource-ref>
最后访问这个的代码。这段代码是反编译一个jar的结果,它不是第三方jar,但我没有源代码。异常发生在 jndiReference = ic.lookup(serviceName);
行。 serviceName
为资源名称,jndiRoot
始终为null(调用该方法的代码传入null)。 getInitialContext()
方法只是创建一个 javax.naming.InitialContext
的新实例(如果尚未创建的话)。
public static URL getUrl(final String serviceName, final String jndiRoot) {
URL result = null;
if (!isEmpty((Object) serviceName)) {
final InitialContext ic = getInitialContext();
Object jndiReference = null;
try {
jndiReference = ic.lookup(serviceName);
} catch (NamingException ex) {
ex.printStackTrace();
if (!isEmpty((Object) jndiRoot)) {
final String name = String.valueOf(jndiRoot) + serviceName;
try {
jndiReference = ic.lookup(name);
} catch (NamingException ex2) {
ex.printStackTrace();
}
}
}
if (jndiReference instanceof URL) {
result = (URL) jndiReference;
} else if (jndiReference instanceof Reference) {
final Reference reference = (Reference) jndiReference;
final RefAddr refAddr = reference.get("spec");
try {
result = new URL(getString(refAddr.getContent()));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
return result;
}
属性文件中映射到资源的行 propertyserviceurl=url/LOGIN_MODULE_CONFIGURATION_SERVICE
我也曾尝试将 ResourceLink 添加到 Tomcats context.xml。我试过使 ResourceLink 的名称唯一,并且 global 的值与实际资源相同。还尝试修改 属性 文件以映射到 ResourceLink 名称而不是 Resource 但我总是得到相同的结果。
<ResourceLink name="url/LOGIN_MODULE_CONFIGURATION_SERVICE"
global="url/LOGIN_MODULE_CONFIGURATION_SERVICE" type="java.net.URL" />
异常
javax.naming.NameNotFoundException: Name [url/LOGIN_MODULE_CONFIGURATION_SERVICE] is not bound in this Context. Unable to find [url].
at org.apache.naming.NamingContext.lookup(NamingContext.java:816)
at org.apache.naming.NamingContext.lookup(NamingContext.java:173)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:163)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.mycompany.common.supplement.web.WebHelper.getUrl(WebHelper.java:739)
我在这上面花了几天时间,但我无法弄清楚我需要什么配置才能让它工作。我认为最大的障碍是我无法更改尝试访问资源的 java 代码。
我让它工作了。我真的不明白 ResourceLink 是如何工作的,因为它的名称在任何地方都没有被引用。但是,如果有任何不同,它将不起作用。基本上我需要将 java:/comp/env/
添加到资源名称的开头,因为我无法更新调用它的代码。
已将 Tomcats 中的资源 server.xml 更新为
<Resource name="java:/comp/env/url/LOGIN_MODULE_CONFIGURATION_SERVICE" auth="Container"
type="java.net.URL" factory="com.mycompany.objectfactory.JndiUrlObjectFactory"
url="AValidUrl" />
已将 Tomcats context.xml 中的 ResourceLink 更新为
<ResourceLink name="url/LOGIN_MODULE_CONFIGURATION_SERVICE"
global="java:/comp/env/url/LOGIN_MODULE_CONFIGURATION_SERVICE" type="java.net.URL" />
将属性文件条目更新为
propertyserviceurl=java:/comp/env/url/LOGIN_MODULE_CONFIGURATION_SERVICE