In tomcat9 there is a setting in context.xml:
<Resource name="jdbc/db2xx" auth="Container"
type="javax.sql.DataSource" driverClassName="com.ibm.db2.jcc.DB2Driver"
maxTotal="100" maxIdle="30"
maxWaitMillis="-1" username="xx" password="xx"
url="jdbc:db2://xxxx:xxx/dbname;" />
and in Java is :
try {
Class.forName("com.ibm.db2.jcc.DB2SimpleDataSource");
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:/comp/env");
com.ibm.db2.jcc.DB2SimpleDataSource ds = (com.ibm.db2.jcc.DB2SimpleDataSource) envContext.lookup("jdbc/db2xx");
ds.setClientProgramName("MyApplication");
conn = ds.getConnection();
}
But I get error :
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp2.BasicDataSource cannot be cast to com.ibm.db2.jcc.DB2SimpleDataSource
Do I have to change
org.apache.tomcat.dbcp.dbcp2.BasicDataSource
where ?
The main point is
ds.setClientProgramName("MyApplication");
because I would like to see
MyApplication in APPLICATION_NAME
when I run
SELECT APPLICATION_NAME FROM TABLE(MON_GET_CONNECTION(CAST(NULL AS BIGINT),-2))
or is there any other way ?
If I am using javax.sql.DataSource program works, but I can not use setClientProgramName.
In maven pom :
<dependency>
<groupId>com.ibm.db2</groupId>
<artifactId>jcc</artifactId>
<version>11.5.7.0</version>
</dependency>
Client info properties support by the IBM Data Server Driver for JDBC and SQLJ.
ApplicationName
ClientAccountingInformation
ClientHostname
ClientUser
These properties mentioned at the link above can't be set with URL.
They can be set with the JDBC 4 method (use db2jcc4.jar, not db2jcc.jar which is JDBC 3 implementation) setClientInfo only like below:
conn = ds.getConnection();
conn.setClientInfo("ApplicationName", "MyApplication");
Related
I am trying to connect to my Database in AppConfig.class :
#PropertySource("classpath:persistence-jndi.properties")
public class AppConfig {
by JNDI name :
#Bean
public DataSource dataSource() throws NamingException {
String pathProperties = environment.getProperty("URL");
return (DataSource) new JndiTemplate().lookup(pathProperties);
}
persistence-jndi.properties : URL = java:comp/env/jdbc/task11dao
web.xml :
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<resource-ref>
<res-ref-name>jdbc/task11dao</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
context.xml ( main - webapp - META-INF - context.xml ) :
<GlobalNamingResources>
<ResourceLink name="jdbc/task11dao" auth="Container"
type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:3306/task11dao"
username="postgres" password="postgres" maxActive="20" maxIdle="10" maxWait="-1"/>
</GlobalNamingResources>
And when I run my Tomcat Server, I gain an exception ( below you can see the stacktrace ) :
Caused by: org.springframework.jdbc.datasource.init.UncategorizedScriptException: Failed to execute database script; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Data source is closed
at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:59)
at org.springframework.jdbc.datasource.init.DataSourceInitializer.execute(DataSourceInitializer.java:111)
at org.springframework.jdbc.datasource.init.DataSourceInitializer.afterPropertiesSet(DataSourceInitializer.java:96)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1862)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1799)
... 33 common frames omitted
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC
Connection; nested exception is java.sql.SQLException: Data source is closed
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:82)
at
org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:47)
... 37 common frames omitted
Caused by: java.sql.SQLException: Data source is closed
at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2087)
at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1563)
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:158)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:116)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:79)
... 38 common frames omitted
If I connect without JNDI, just :
#Bean
DataSource dataSource() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setUrl(environment.getProperty(URL));
driverManagerDataSource.setUsername(environment.getProperty(USER));
driverManagerDataSource.setPassword(environment.getProperty(PASSWORD));
driverManagerDataSource.setDriverClassName(environment.getProperty(DRIVER));
return driverManagerDataSource;
}
everything is fine.
I have built a spring boot war file using maven, When I try to deploy the war file to an external tomcat server in command prompt. I get an exception.
Error creating bean with name 'inMemoryDatabaseShutdownExecutor' defined in class path resource [org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.class]: Unsatisfied dependency expressed through method 'inMemoryDatabaseShutdownExecutor' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: oracle.jdbc.OracleDriver
I am using two application.properties files one in src/main/resources that has the actual datasource config to Oracle and another in src/test/resources that has a datasource for a H2 in memory database.
Please let me know if I missed anything, Like placing the property file in config under tomcat folder etc.
I suppose you have set oracle.jdbc.OracleDriver as driver-class-name on your application.properties under src/main/java, right? Did you remember to include this dependency on pom.xml similar to what follows?
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
</dependency>
Edit
Try adding this to tomcat's context.xml:
<Resource name="jdbc/mydb" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
username="xxx" password="xxx" driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#localhost:1521:xe"/>
Okay, The root cause of this is there is no oracle6 jar in my war file - Even though I added the dependency in my pom.xml.
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>6</version>
<scope>system</scope>
<systemPath>${basedir}/lib/ojdbc6.jar</systemPath>
</dependency>
Therefore I've added the jar explicitly into my Tomcat lib and it worked.
I added the Datasource Configuration using the programmatic way as below and it worked, not sure why couldn't it be picked from application.properties.
#Configuration
public class DatasourceConfig {
#Bean
public DataSource datasource() {
return DataSourceBuilder.create()
.driverClassName("com.mysql.cj.jdbc.Driver")
.url("jdbc:mysql://localhost:3306/test_db")
.username("username")
.password("password")
.build();
}
}
Credits to Baeldung article here
I am using JNDI datasource to connect to Postgres database. This is the code to of my ServletContextListener
public void contextInitialized(ServletContextEvent event) {
try {
// Obtain our environment naming context
Context envCtx = (Context) new InitialContext().lookup("java:comp/env");
// initialize JNDI lookup parameters
DataSource datasource = (DataSource) envCtx.lookup("jdbc/testdb");
ManagerDao.getConn(datasource);
ParticipantDao.getConn(datasource);
EventDao.getConn(datasource);
FacilitiesDao.getConn(datasource);
}
catch (NamingException e) {
e.printStackTrace();
}
}
web.xml of App_path\WebContent\WEB-INF
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/testdb</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
context.xml
<Resource name="jdbc/testdb"
auth="Container"
type="javax.sql.DataSource"
username="postgres"
password="rules#123"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5433/eventory"
maxActive="20" maxIdle="10"
/>
But I am getting errors while the getConnection() methods are getting called.
java.sql.SQLException: Cannot create JDBC driver of class '' for connect URL 'null'
at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createConnectionFactory(BasicDataSource.java:2167)
at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2037)
at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1543)
at com.eventory.dao.FacilitiesDao.getConn(FacilitiesDao.java:26)
at com.eventory.initDB.DBConnListener.contextInitialized(DBConnListener.java:48)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4745)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5207)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.sql.SQLException: No suitable driver
at java.sql.DriverManager.getDriver(Unknown Source)
at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createConnectionFactory(BasicDataSource.java:2151)
... 13 more
I have tried the following approaches:
Put the postgresql-42.1.4.jar in the tomcat lib folder.
Put the postgresql-42.1.4.jar in the App_Path\WebContent\WEB-INF\lib
Put the context.xml in the WebContent\META-INF folder
Put the context.xml in the tomcat\conf folder
Nothing seems to work. Is there any other approach that I missed? Please help.
I'm seeing the following error during Tomcat shutdown:
Jan 04, 2015 4:14:31 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [] registered the JDBC driver [org.apache.derby.jdbc.AutoloadedDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
I understand Tomcat forcibly unregistered the driver to prevent a memory leak.
However, how to fix and who is responsible for fixing this issue -- me, Tomcat DBCP, or Derby?
I'm using Tomcat 7.0.47 and Derby 10.11.1.1
context.xml for Tomcat:
<Context>
<Resource name="jdbc/db" auth="Container" type="javax.sql.DataSource"
driverClassName="org.apache.derby.jdbc.EmbeddedDriver"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
maxActive="100"
minIdle="2"
maxIdle="30"
maxWait="10000"
validationQuery="VALUES 1"
testOnBorrow="true"
removeAbandoned="true"
url="jdbc:derby:dev;create=true"
username="root"
password="root"
/>
</Context>
Similar questions I found on Google referenced DERBY-4895, but that issue has been fixed a while ago.
You can simply ignore it, or you can create a ServletContextListener that deregisters the drivers at app shutdown:
public class MyContextListener implements ServletContextListener{
#Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("App shutdown ...");
System.out.println("Deregistering SQL-Drivers ...");
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
System.out.println(driver.getClass().getName());
} catch (SQLException e) {
System.err.println("Error deregistering driver " + driver.getClass().getName());
}
}
}
#Override
public void contextInitialized(ServletContextEvent arg0) {
}
}
Of course you need to add the listener to your web.xml, or annotate it with #WebListener.
I am trying to create a Tomcat JNDI resource for MSSQL database.
This is how my resource string looks in tomcat context.xml file
<Resource
name="jdbc/FI/SD"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://LDIA;databaseName=SD"
validationQuery="Select 1"
maxActive="1" maxIdle="1" maxWait="10000"
user="rels"
password="hidden"
/>
This is the code snippet that i am using in Servlet to check datasource:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)envCtx.lookup("jdbc/FI/SD");
Connection conn = ds.getConnection();
but i am getting this error while creating connection at line 4,
how can i solve this:
org.apache.tomcat.dbcp.dbcp.SQLNestedException:
Cannot create PoolableConnectionFactory (Login failed for user ''. The user is not associated with a trusted SQL Server connection.)
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549)
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1388)
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
at com.MyServlet.doGet(MyServlet.java:40)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
Maybe user should be username instead?