Tomcat removeAbandoned property causing exception - java

I am trying to add the removeAbandoned attribute to a resource in an environment running Tomcat 5.5. Before adding this attribute, the servlet running in this environment works fine. As soon as I add the attribute an exception is thrown as follows:
EXCEPTION javax.naming.NamingException: No set method found for property: removeAbandoned.
I do not understand why this is happenning. As soon as I remove the attribute, the servlet works again.
Below is the entire Context tag as it appears in my environment:
<Context path="/emscribe" docBase="emscribe" debug="0" reloadable="true"
crossContext="true">
<Logger className="org.apache.catalina.logger.FileLogger" prefix="emscribe_log."
suffix=".txt" timestamp="true"/>
<Resource name="jdbc/emscribe" auth="Container"
type="com.mchange.v2.c3p0.ComboPooledDataSource" driverClass="com.mysql.jdbc.Driver"
maxPoolSize="100" minPoolSize="5"
acquireIncrement="5" removeAbandoned="true"
user="aUserID"
password="aPassword"
factory="org.apache.naming.factory.BeanFactory"
jdbcUrl="jdbc:mysql://127.000.71.101/emscribedx?autoReconnect=true"
/>

Your exception:
javax.naming.NamingException: No set method found for property: removeAbandoned.
states that it can't find a method getRemoveAbandoned() and setRemoveAbandoned(boolean removeAbandoned) from the type specified in your resource.
The removeAdandoned property can only be used with Apache DBCP BasicDataSource.
So, your resource jdbc/emscribe type must not be com.mchange.v2.c3p0.ComboPooledDataSource but rather org.apache.commons.dbcp.BasicDataSource.
Hope this helps.

removeAdandoned would not work with cp30 connection pooling. Its for DBCP on older tomcat versions or apache connection pooling introduced in tomcat 7

Related

Cannot cast from ConnectionWrapper to oracle.jdbc.OracleConnection using JAVA1.8 and Tomcat 8.5.28

Why connection is not working after few seconds? Application is hanging up and not running as expected and returning the below error.
java.lang.ClassCastException:
org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper
cannot be cast to org.apache.tomcat.dbcp.dbcp2.DelegatingConnection
Below is the code that is used to get the connection:
OracleConnection oracleConnection = (OracleConnection)
((DelegatingConnection)connection).getInnermostDelegate();
using libraries: commons-pool1.6.jar for encryption & tomcat-dbcp.jar for database.
Using encrypted username and password in Tomcat context.xml.
Also, using accessToUnderlyingConnectionAllowed=true in context.xml file.
Issue is with JAVA8 and Tomcat8. Able to work properly with plain credentials, the only issue happens with encrypted credentials.
You shouldn't do casting or unwrapping. Use correct DataSource type in Tomcat 'conf/context.xml' file. In case of Oracle it is: oracle.jdbc.pool.OracleDataSource.
Set also correct driver and factory.
Look at this example of mine:
<Context>
<!-- Default set of monitored resources. If one of these changes, the -->
<!-- web application will be reloaded. -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<Resource name="UNCUNC"
auth="Container"
type="oracle.jdbc.pool.OracleDataSource"
factory="oracle.jdbc.pool.OracleDataSourceFactory"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#p260unc4.big.ru:1566:uncunc"
user="dsserv"
password="dsservPass"
connectionProperties="SetBigStringTryClob=true"
maxTotal="20" maxIdle="10"
maxWaitMillis="-1"/>
<JarScanner scanManifest="false"/>
Later in the java code use it like this (don't cast):
try {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("UNCUNC");
} catch (NamingException e) {
logger.error("DATASOURCE error", e);
}
Connection conn = ds.getConnection();
Should work just fine. Take attention in different versions of Tomcat you need to use 'username' instead 'user' field.
I faced the same issue. After a lot of analysis realized it was classloading issue. Fixed the issue by providing ojdbc jar in shared.loaded (in conf/catalina.properties)
shared.loader="/path/to/ojdbcN_jar/ojdbcN.jar"
This will make sure that the OracleConnection classes are loaded from the same jar in Tomcat and in the deployed webapp.
And in the application where OracleConnection is needed, use the below:
OracleConnection oracleConnection = connection.unwrap(OracleConnection.class);
Note: In my application I have ojdbc jar so that my application compiles fine, but when deployed, the jar used will be the one mentioned in shared loader.
Also don't forget to enable accessToUnderlyingConnectionAllowed when creating the Tomcat JDBC connection pool

javax.naming.NameNotFoundException: Name [jdbc/rhwebDB] is not bound in this Context. Unable to find [jdbc]

I know there's many questions regarding this exception, however, I believe I've tried everything for many days, without any luck yet. As this is a production server, I can only work on this after midnight :(
I have a Tomcat app. Recently, I've updated the connection pool, in order to use Tomcat's jdbc-connection pool. In my Windows developing machine, everything works fine, but now that I'm trying to implement this on my Linux Server, I get this exception (see title) when ever my app tries to connect to MySQL.
I'm using "Easy Tomcat 7" which is supposed to be the same as the regular version of Tomcat, only it comes with the CPanel software.
I just need this DB to be available for this app (not multiple app's).
This is my java DB class:
public class DBUtil {
static DataSource ds;
static {
try {
Context context = new InitialContext();
ds = (DataSource)context.lookup("java:comp/env/jdbc/rhwebDB");
} catch (NamingException e) {
e.printStackTrace();
System.out.println("DBUtil.NamingException" + e);
} catch(Exception e) {
System.out.println(e);
}
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
This is my context.xml file, which is located on myAppDirectory/META-INF
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource
name="jdbc/rhwebDB"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="20"
minIdle="3"
maxIdle="15"
maxWait="10000"
initialSize="3"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="30000"
username="dbuser"
password="dbpwd"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/rhmexweb_rhweb"/>
</Context>
I don't use WAR files. I just upload files to my server and re-start tomcat when needed, which normally works just fine.
In case this is relevant too, Tomcat's server.xml file has this settings for this website. I've also tried adding parameter copyXML="true", with no luck so far:
<Host name="rhweb.net" appBase="webapps">
<Alias>www.rhweb.net</Alias>
<Context path="" reloadable="false" docBase="/home/rhweb/public_html" debug="1"/>
</Host>
Here's the full stacktrace I get when my app tries to establish a connection with MySQL:
javax.naming.NameNotFoundException: Name [jdbc/rhwebDB] is not bound in this Context. Unable to find [jdbc].
at org.apache.naming.NamingContext.lookup(NamingContext.java:820)
at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
at org.apache.naming.NamingContext.lookup(NamingContext.java:831)
at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
at org.apache.naming.NamingContext.lookup(NamingContext.java:831)
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:415)
at util.DBUtil.<clinit>(DBUtil.java:23)
at Solutio.AdminRH.Entity.ISeguridadAdminDB.verificaUsuario(ISeguridadAdminDB.java:142)
at org.apache.jsp.menu_jsp._jspService(menu_jsp.java:115)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:200)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
I've also tried adding these lines in my app's web.xml file (which I hadn't had to include in my windows machine)
<resource-ref>
<description>MySQL RhWeb Datasource</description>
<res-ref-name>jdbc/rhwebDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
And when I include those lines, the exception I get is this one:
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
It seems that Tomcat can't find my META-INF/context.xml file, or it doesn't recognize this link:
ds = (DataSource)context.lookup("java:comp/env/jdbc/rhwebDB");
My linux, Tomcat and JDK versions are:
CentOS release 6.8 (Final)
Apache Tomcat/7.0.42
java version "1.7.0_131"
I don't know what else can I try to fix this. Any help will be really appreciated
UPDATE
I still haven't found a solution yet. I've realized some probable configuration issues that may be related to all this:
The app is located here:
/home/rhmexweb/public_html
However, on the Tomcat's server.xml file the host definition for this website is:
<Host name="rhweb.mx" appBase="webapps">
<Context path="" reloadable="false" docBase="/home/rhmexweb/public_html" />
</Host>
The reason why is not located on the webapps directory, is because CPanel automatically creates every account in /home/account-name/public_html, so that's why a context element is needed here (I guess). If I remove the whole Context tag, and instead I use appBase="/home/rhmexweb/public_html", then Tomcat won't find all the jars and content from the WEB-INF folder (/home/rhmexweb/public_html/WEB-INF). I mentioned this because I added the parameter copyXML="true" just to see where would tomcat tries to copy context.xml file, and if it changes it's name, but it turns out that there are two different paths. First I got a writing permissions exception when I first include that parameter, and it was trying to create a folder here:
/var/lib/easy-tomcat7/webapps/
This path, only contains folders of the default tomcat app's (manager, examples & host-manager)
The folder where all the websites are listed and all the compiled jsp files are is this one:
/usr/local/easy/etc/easy-tomcat7/Catalina/
however, in /usr/local/easy/etc/easy-tomcat7/Catalina/rhweb.mx/ there is no WEB-INF directory.
Anyway, what I'd like to know is if having a Context element in the host definition might be a problem for Tomcat in order to find the appPath/META-INF/context.xml file.
It looks like there is something wrong with the context.xml setup. Try server.xml or /META-INF/context.xml to see if it behaves any different.
You can try moving the configuration to the server.xml as per Tomcat 7 docs:
<GlobalNamingResources>
<Resource
name="jdbc/rhweb_rhwebDB"
auth="Container"
type="javax.sql.DataSource"
...
/>
</GlobalNamingResources>
link to global resource in the context.xml:
<Context>
<ResourceLink
global="jdbc/rhweb_rhwebDB"
name="jdbc/rhwebDB"
type="javax.sql.DataSource"
/>
</Context>
and then refer to it in /WEB-INF/web.xml like you already do:
<resource-ref>
<res-ref-name>jdbc/rhwebDB</res-ref-name>
<res-ref-type>javax.sql.DataSource</res-ref-type>
<res-auth>Container</res-auth>
</resource-ref>
If this won't work you can check few other approaches discussed in this answer.
I finally solved it!!
Maybe it's a workaround but it works.
I copied the app-directory/META-INF/context.xml file to:
$CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default
(notice the "default" part of the filename)
As it's stated in the Tomcat's documentation
Now I don't need to add any entry in my app's web.xml file, neither a META-INF/context.xml file in my app directory (which is not located on the Tomcat's/webapps directory)
All I need is to put a context.xml.default file (containing it's DB information) in every folder listed in this path:
$CATALINA_BASE/conf/[enginename]/
which in my server is:
/usr/local/easy/etc/easy-tomcat7/Catalina/
so for this website, I copied it to:
/usr/local/easy/etc/easy-tomcat7/Catalina/myDomain.com/
You'll notice my path is different from the one specified in Tomcat's documentation, and that's because I'm using CPanel's easy-tomcat 7 which has a different structure than the regular Tomcat. That fact made everything more complicated when looking for a solution, even if it's called easy-tomcat.
About why Tomcat could never read the /META-INF/context.xml, that remains a mistery, but honestly, I don't care much since this method it's easier (one file instead of two)

Tomcat can't find JDBC driver under Eclipse?

I'm rebuilding my development environment and I can't get JDBC working. I'm running Tomcat 7 under Eclipse Java EE Mars.2 and am using mysql-connector-java. Also Linux Mint 17.2. I upgraded to latest on a bunch of things but I don't think that's it.
When I start the Tomcat server under Eclipse, I keep getting the following. I'm not running it separately on this machine. Just under Eclipse.
SEVERE:
Servlet.service() for servlet [jsp] in context with path [] threw exception [javax.servlet.ServletException: javax.servlet.jsp.JspException: Unable to get connection, DataSource invalid: "java.lang.NullPointerException"] with root cause
javax.servlet.jsp.JspException: Unable to get connection, DataSource invalid: "java.lang.NullPointerException"
I assume this means it cannot find the driver? All the file structures are the same as my old PC. And the IDE is not complaining about anything missing. It's just when I try to start the server.
I added the mysql-connector-java-5.1.39-bin.jar to the Tomcat/lib folder. Specifically: /opt/apache-tomcat-7.0.69/lib. And I made sure the Server is referencing that folder. I also made sure it is not in the webapp's lib folder. This is how I always did it before.
I assume it's a driver thing. But maybe not? Can someone please suggest a good way to debug this? Because, I'm stumped...
META-INF/context.xml is as it's been from the previous environment. Password is correct and can connect from the IDE no problem.
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/mydbdb"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
testWhileIdle="true" testOnBorrow="true" testOnReturn="false"
validationQuery="SELECT /* ping */" validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="100" minIdle="10" maxWait="10000" initialSize="10"
removeAbandonedTimeout="600" removeAbandoned="true" logAbandoned="true"
minEvictableIdleTimeMillis="30000"
jmxEnabled="true"
username="user" password="password"
useUnicode="true" useEncoding="true" characterEncoding="UTF-8"
url="jdbc:mysql://localhost:3306/mydb?useOldAliasMetadataBehavior=true&zeroDateTimeBehavior=convertToNull"
/>
<Resource name="mail/MailSession"
auth="Container"
type="javax.mail.Session"
mail.smtp.auth="false"
mail.smtp.host="localhost"
/>
</Context>
It is with great embarrassment that I admit I forgot to copy the web.xml file from the old environment... Doh! Sitting so close... Sometimes you can't see the forest for the trees.
If you double-click your Tomcat instance under Eclipse it will take you to the setting for the server, and from there you can select the "Open Launch Configuration" option where you can add your driver jar to the bootstrap classpath.
That said, I don't think the problem is a missing driver as that generally results in a "Class not found" exception. Check your logs carefully and maker sure you're not getting any errors. I'm making the assumption that you're letting Tomcat open your database connections to create a datasource. It seems like you don't have your data source configured in your Tioomcat server.xml and context.xml and therefore your servlet is throwing a null pointer exception when trying to use it.

X509UsernameRetrieverClassName ignored in tomcat 6 configuration

we have configured a JNDIRealm for our tomcat 6.0.32 installation.
Clients gain access to the webapp via Client-Cert authentication. The username
extracted from the certificate is of the form "CN=..., OU=.., O=.., L=.., ST=.."
Since we are only interested in the value of CN we wrote a X509UsernameRetrieverClass, placed the jar in $TOMCAT_HOME/lib and
configured it in the JNDIRealm:
<Context docBase="MYApp.war" path="/myapp" reloadable="true">
<Realm
X509UsernameRetrieverClassName="com.my.custom.X509UsernameRetriever"
authentication="simple"
className="org.apache.catalina.realm.JNDIRealm"
connectionName="ldapuser"
connectionPassword="****"
connectionURL="ldap://localhost:389"
roleBase="xxxx"
roleName="cn"
roleSearch="(member={0})"
roleSubtree="true"
userBase="xxxx"
userSearch="(cn={0})"
userSubtree="true"/>
</Context>
However, when tomcat boots up we get the following warning:
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context/Realm} Setting property 'X509UsernameRetrieverClassName' to 'com.my.custom.X509UsernameRetriever' did not find a matching property.
The configuration is ignored and users aren't authenticated, presumably because the defaut retriever is used returning the long winded username which isn't found
in the underlying ldap system...
The same configuration works fine for tomcat 7. I can't really see what we did wrong. The X509UsernameRetrieverClassName is documented. https://tomcat.apache.org/tomcat-6.0-doc/config/realm.html#JNDI_Directory_Realm_-_org.apache.catalina.realm.JNDIRealm
does anyone have any ideas ?
thanks,
Michael
solved the problem.
the X509UsernameRetriever class doesn't appear in tomcat 6 until version 6.0.36. hence the attribute being ignored in version 6.0.32
The workaround was to override the JNDIRealm.getPrincipal(X509Certificate usercert) in a custom class.

incorrect config.xml [duplicate]

This question already has answers here:
publishing failed with multiple errors eclipse
(8 answers)
Closed 8 years ago.
What is incorrect in my config.xml file for tomcat 7.0
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Manager pathname="" />
<Resource name="jdbc/mkyongdb" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="user" password="12345" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/mkyongdb"/>
</Context>
An error occurs when I`m publishing the application on the server:
Could not load the Tomcat server configuration at \Servers\Tomcat v7.0
Server at localhost-config. The configuration may be corrupt or
incomplete. Resource is out of sync with the file system:
/Servers/Tomcat v7.0 Server at localhost-config/context.xml.
But now this error occurs:
Could not load the Tomcat server configuration at \Servers\Tomcat v7.0
Server at localhost-config. The configuration may be corrupt or
incomplete. Element type "Resource" must be followed by either
attribute specifications, ">" or "/>".
Are you using Eclipse? If so, perhaps this question might be helpful:
publishing failed with multiple errors eclipse
If you're not using Eclipse let me know and I'll delete my answer :)
Could not load the Tomcat server configuration at \Servers\Tomcat v7.0
Server at localhost-config. The configuration may be corrupt or
incomplete. Element type "Resource" must be followed by either
attribute specifications, ">" or "/>".
if you want to run your program without any error, change your workspace with different name and again develop and deploy your application i am sure it will run ..........

Categories