问题
What I'm trying to do is to update my database after a period of time. So I'm using java scheduler and connection pooling. I don't know why but my code only working once. It will print:
init success
success
javax.naming.NameNotFoundException: Name [comp/env] is not bound in this Context. Unable to find [comp].
at org.apache.naming.NamingContext.lookup(NamingContext.java:820)
at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:158)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at test.Pool.main(Pool.java:25) ---> line 25 is Context envContext = (Context)initialContext.lookup("java:/comp/env");
I don't know why it only works once. I already test it if I didn't running it without java scheduler and it works fine. No error whatsoerver. Don't know why i get this error if I running it using scheduler.
Hope someone can help me.
My connection pooling code:
public class Pool {
public DataSource main() {
try {
InitialContext initialContext = new InitialContext();
Context envContext = (Context)initialContext.lookup("java:/comp/env");
DataSource datasource = new DataSource();
datasource = (DataSource)envContext.lookup("jdbc/test");
return datasource;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
my web.xml:
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<listener>
<listener-class> package.test.Pool</listener-class>
</listener>
<resource-ref>
<description>DB Connection Pooling</description>
<res-ref-name>jdbc/test</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/project" reloadable="true">
<Resource auth="Container"
defaultReadOnly="false"
driverClassName="com.mysql.jdbc.Driver"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
initialSize="0"
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
jmxEnabled="true"
logAbandoned="true"
maxActive="300" maxIdle="50"
maxWait="10000"
minEvictableIdleTimeMillis="300000"
minIdle="30"
name="jdbc/test"
password="test"
removeAbandoned="true"
removeAbandonedTimeout="60"
testOnBorrow="true"
testOnReturn="false"
testWhileIdle="true"
timeBetweenEvictionRunsMillis="30000"
type="javax.sql.DataSource"
url="jdbc:mysql://localhost:3306/database?noAccessToProcedureBodies=true"
username="root"
validationInterval="30000"
validationQuery="SELECT 1"/>
</Context>
my java scheduler
public class Scheduler extends HttpServlet{
public void init() throws ServletException
{
System.out.println("init success");
try{
Scheduling_test test = new Scheduling_test();
ScheduledExecutorService executor = Executors.newScheduledThreadPool(100);
ScheduledFuture future = executor.scheduleWithFixedDelay(test, 1, 60 ,TimeUnit.SECONDS);
}catch(Exception e){
e.printStackTrace();
}
}
}
Schedule_test
public class Scheduling_test extends Thread implements Runnable{
public void run(){
Updating updating = new Updating();
updating.run();
}
}
updating
public class Updating{
public void run(){
ResultSet rs = null;
PreparedStatement p = null;
StringBuilder sb = new StringBuilder();
Pool pool = new Pool();
Connection con = null;
DataSource datasource = null;
try{
datasource = pool.main();
con=datasource.getConnection();
sb.append("SELECT * FROM database");
p = con.prepareStatement(sb.toString());
rs = p.executeQuery();
rs.close();
con.close();
p.close();
datasource.close();
System.out.println("success");
}catch (Exception e){
e.printStackTrace();
}
}
回答1:
This error shows that your jdbc resource is not registered! Where did you put your context.xml
?
The context.xml
file must be in the META-INF
directory of the war file. It must not be in the classes directory or in a jar file.
Put the META-INF
directory with the context.xml
in the directory containing the root of the webapp in your source folder tree.
回答2:
Try stopping and restarting your server (I assume you are using Eclipse and a Tomcat server). Maybe when you created your context xml file as it did was empty initially, your server was not able to synchronize its contents hence its inability to find the database connection resource name you later specified in the context.xml file.
i.e. if you have not already solved this problem.
回答3:
I had the same problem which dragged on for two painful days. I Re-read tomcat documentation about JNDI, confirmed all my server.xml
, context.xml
,web.xml
configuration and the code to access the naming object... still no progress.
It turned out to be a dependency in my project that was interfering with the naming context - axis2. A simple move from axis2-1.6.0 to axis2-1.6.2 caused my problem.
回答4:
It's not java:/comp/env
but java:comp/env
.
回答5:
This problem is likely to arise when two versions of a same module are present.
Kindly check the lib
folder for multiple versions of the same module.
Remove the version that you don't need and restart the server.
In my case it was servlet-api
present in two versions servlet-api.jar
servlet-api-2.jar
Hope this solves your problem. Good day!
回答6:
I just ran in the same issue. In my case there was nothing wrong with my tomcat configuration files or my project but I had to restart my postgres service instance as my tomcat was running and it would somehow pick up the change and the exception disappeared. I had to restart windows for the problem to go away completely. No idea why!
来源:https://stackoverflow.com/questions/12213246/javax-naming-namenotfoundexception-name-comp-env-is-not-bound-in-this-context