I am trying to use GlobalNamingResources to create a global bean that will be used by 2 different webapps (on the same tomcat of course).
My problem is that I get a NullPointerException when I try to set new data to the class I got from the JNDI.
I followed the following link, and I am still not sure what I did wrong: http://tomcat.apache.org/tomcat-7.0-doc/config/globalresources.html
This is the line that crashes my servlet:
single.setText("TEXT");
this is my test servlet:
@WebServlet("/JNDIServlet")
public class JNDIServlet extends HttpServlet {
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Thread.sleep(4000);
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
SingletonClass single = (SingletonClass) envCtx.lookup("TestMe");
single.setText("TEXT");
initCtx.rebind("TestMe", single);
response.getWriter().println(envCtx.lookup("TestMe").toString());
} catch (NamingException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
my "SingletonClass" is just a pojo:
package com.jndi.test;
public class SingletonClass {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public SingletonClass() {
}
}
this is my web.xml file:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>JNDIServletTest</display-name>
<resource-ref>
<res-ref-name>TestMe</res-ref-name>
<res-type>com.jndi.test.SingletonClass</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
and finally, the relevant part from my server.xml file from the tomcat:
<GlobalNamingResources>
<Resource name="TestMe" auth="Container"
type="com.jndi.test.SingletonClass"
factory="org.apache.naming.factory.BeanFactory"/>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
</GlobalNamingResources>
also, I have added the needed Resource link in the context.xml in my tomcat:
<ResourceLink name="TestMe" global="TestMe" type="com.jndi.test.SingletonClass"/>
Can anyone please provide me some insight about what I did wrong?
Thanks a lot :)
[SOLVED]
Part 1:
In ResourceLink
of webapp's context.xml
, use a different name
from that used for global
name
defined for Resource
in server.xml
Part 2:
Remove duplicate implementation JARs/classes of the resource bean from-webapp's-lib and keep the ones placed in tomcat lib.
Part 2 Explained:
In my case, i had created a factory in a separate package and packaged it as a JAR. I was using the JAR in both webapp's lib and tomcat lib.
This resulted in a ClassCastException
(caused as the Resource was created with tomcat's version class - and then the application tried to cast it to the class from it's own lib [if interested, read a little more about ClassLoaders in tomcat, which will make things a lot clearer]).
Reference: JNDI ClassCastException
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.