How to get resource from the context.xml file in tomcat webapp? - java

This is my context.xml file:
...
<Resource auth="Container"
driverClass="net.sourceforge.jtds.jdbc.Driver"
type="com.jolbox.bonecp.BoneCPDataSource"
idleMaxAge="240"
idleConnectionTestPeriod="60"
partitionCount="3"
acquireIncrement="1"
maxConnectionsPerPartition="10"
minConnectionsPerPartition="3"
statementsCacheSize="50"
releaseHelperThreads="4"
name="jdbc/MyDatasource"
username="my_username"
password="my_password"
factory="org.apache.naming.factory.BeanFactory"
jdbcUrl="jdbc:jtds:sqlserver://localhost:12345/my_database"
/>
...
I already tried using ServletContext.getResource(java.lang.String) with the name of the resource ("jdbc/MyDatasource"), but Tomcat complains that the name doesn't begin with a '/'. I also tried with "/jdbc/MyDatasource", but this time it returns null.
I mainly need the jdbcUrl to perform a connection check with the database server (see if the server is online and operational).

Keyword is: JNDI. The resources in the context.xml are not 'System Resources' but JNDI Resources.
Try this:
InitialContext ic = new InitialContext();
// that's everything from the context.xml and from the global configuration
Context xmlContext = (Context) ic.lookup("java:comp/env");
DataSource myDatasource = (DataSource) xmlContext.lookup("jdbc/MyDatasource");
// now get a connection to see if everything is fine.
Connection con = ds.getConnection();
// reaching this point means everything is fine.
con.close();

You should be able to access the datasource with the following code:
Context initialContext = new InitialContext();
Context envContext = (Context)initialContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/MyDatasource");

Related

Using datasource connection of weblogic server

I have wrote Java Client application (bean for Oracle form) to access the data through "jdbcdatasource" created on Weblogic 12c. It works fine when I am running on desktop, but when I am embedding on oracle forms as a bean, it gives following error:
java.lang.ClassNotFoundException: weblogic.jdbc.common.internal.RmiDataSource_12210_WLStub
java bean is an executable jar file includes all the dependency jar file, and it is executed independently by double click.
Here is a code:
Context ctx = null;
Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL, "t3:" + url + ":7001");
if(sUser != null && sPwd != null){
ht.put(Context.SECURITY_PRINCIPAL, sUser);
ht.put(Context.SECURITY_CREDENTIALS, sPwd);
}
ctx = new InitialContext(ht);
System.out.println("!!! WebLogic Server Connection Done!");
javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup("myDatasource");
java.sql.Connection conn = ds.getConnection();
System.out.println("!!! DataSource Connection Done!");
In the environment of Oracle forms it connect to the weblogic server but could not access the data source by displaying above error.
Any suggestion?
Just to make things clear to me.
When you say :
"to access the data through "jdbcdatasource" created on Weblogic 12c."
and you code shows:
"javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup("myDatasource");"
The lookup parameter value shouldn't be exactly like "jdbcdatasource" instead of "myDataSource' as you stated before or it was just to explain your situation ?

Setting JDBC Properties Using DataSource

I am connecting to a mysql database using the DataSource object.
DataSource mysql = (DataSource) context.lookup("jdbc/MySQLDataSource");
Connection conn = mysql.getConnection();
I want to set the property
rewriteBatchedStatements=true
for when I am doing some batch uploads. I have seen examples how to do this when people are using a driver manager like below:
String myConnectionString =
"jdbc:mysql://localhost:3307/mydb?" +
"useUnicode=true&characterEncoding=UTF-8" +
"&rewriteBatchedStatements=true";
try (Connection con = DriverManager.getConnection(myConnectionString, "root", "whatever"))
How do I go about setting this property using the DataSource?
Adding to #aguibert answer, you can configure the same at global level as well, by editing the url of your Resource name as below:
<Resource name="jdbc/MySQLDataSource" auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3307/mydb?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8"
username="root"
password="root"
maxActive="100"
maxIdle="20"
maxWait="10000"/>
If you cast your datasource to the specific implementation you're using, you will be able to use all the get/set methods specific to the jdbc driver you are using.
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
//...
MysqlDataSource mysql = (MysqlDataSource) context.lookup("jdbc/MySQLDataSource");
mysql.setRewriteBatchedStatements(true);
Connection conn = mysql.getConnection();
See this link for reference: http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html
I have fixed this by doing the following steps:
DataSource datasource = (DataSource) context.lookup("jdbc/MySQLDataSource");
MysqlDataSource mysql_datasource = datasource.unwrap(MysqlDataSource.class);
mysql_datasource.setRewriteBatchedStatements(true);
Connection conn = mysql.getConnection();
Everything worked smoothly then. This extra unwrap() call was needed because I was attempting this on glassfish. Check the answer by aguibert below for further information.

Access the DataSource from the stand alone application

I have created the data source in Websphere server and its name is myDataSource(JNDI name is oracleDS). Now I want to access it through the stand alone application.
I just wrote the bellow code to access the data sorce.
Hashtable<String, String> pdEnv = new Hashtable<String, String>();
pdEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
pdEnv.put(Context.PROVIDER_URL, "iiop://localhost:2809");
Context initialContext = new InitialContext(pdEnv);
DataSource dataSource = (DataSource) initialContext
.lookup("java:comp/env/jdbc/oracleDS");
But when I run the application I am getting the bellow exception.
Aug 6, 2013 11:33:41 PM null null
SEVERE: javaAccessorNotSet
javax.naming.ConfigurationException: Name space accessor for the java: name space has not been set. Possible cause is that the user is specifying a java: URL name in a JNDI Context method call but is not running in a J2EE client or server environment.
Please let me know do I have to do any configuration changes in websphere to access the data source or any other code level changes do I have to do?
Please confirm me can we access the datasource from outside of the container(websphere)?
Update1:
I followd the way which PhilipJ mentioned. Then I am gtting the bellow exception.
SEVERE: Cannot get connection: javax.naming.NameNotFoundException: Context: LTC-VIRTUS-24WZNode01Cell/nodes/LTC-VIRTUS-24WZNode01/servers/server1, name: jdbc/oracleDS: First component in name oracleDS not found. [Root exception is org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0]
javax.naming.NameNotFoundException: Context: LTC-VIRTUS-24WZNode01Cell/nodes/LTC-VIRTUS-24WZNode01/servers/server1, name: jdbc/oracleDS: First component in name oracleDS not found. [Root exception is org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0]
at com.ibm.ws.naming.jndicos.CNContextImpl.mapNotFoundException(CNContextImpl.java:4365)
at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1794)
at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1749)
at com.ibm.ws.naming.jndicos.CNContextImpl.lookupExt(CNContextImpl.java:1500)
at com.ibm.ws.naming.jndicos.CNContextImpl.lookup(CNContextImpl.java:637)
at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:165)
at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:179)
at javax.naming.InitialContext.lookup(InitialContext.java:436)
at com.nyl.connection.ConnectionUtil.getConnection(ConnectionUtil.java:38)
at com.nyl.main.Main.main(Main.java:9)
Caused by: org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0
at org.omg.CosNaming.NamingContextPackage.NotFoundHelper.read(NotFoundHelper.java:95)
at com.ibm.WsnOptimizedNaming._NamingContextStub.resolve_complete_info(_NamingContextStub.java:506)
at com.ibm.ws.naming.jndicos.CNContextImpl$2.run(CNContextImpl.java:2797)
at com.ibm.ws.naming.jndicos.CNContextImpl$2.run(CNContextImpl.java:2793)
at com.ibm.ws.naming.util.CommonHelpers.retry(CommonHelpers.java:763)
at com.ibm.ws.naming.jndicos.CNContextImpl.cosResolve(CNContextImpl.java:2791)
at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1790)
... 8 more
Update2:
I found the way to avoid the exception. The code should be bellow,
Hashtable<String, String> pdEnv = new Hashtable<String, String>();
pdEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
pdEnv.put(Context.PROVIDER_URL, "iiop://localhost:2809");
Context initialContext = new InitialContext();
DataSource datasource = (DataSource) initialContext.lookup("oracleDS");
if (datasource != null) {
connection = datasource.getConnection("admin","admin");
} else {
LOGGER.info("Failed to lookup datasource.");
}
But the problem here is I am giving the database credintials to creat the connection. I don't want to give it. Can any one please let me know how to create the connection without giving the database credintials?
I found the solution for this issue.
When we creat the InitialContext we have to set two environment variables correctly as bellow,
Hashtable<String, String> pdEnv = new Hashtable<String, String>();
pdEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
pdEnv.put(Context.PROVIDER_URL, "iiop://localhost:2810");
Context initialContext = new InitialContext(pdEnv);
Note:
We can find the listening port of iiop protocol by using the bellow way,
Login to Webaphere admin console => Server => Server Types => Webspher application servers => Click on the name of the server which we use => Communication => Ports.
Then you can find the port for Port name BOOTSTRAP_ADDRESS.
Working code to create the connection using the datasource
Hashtable<String, String> pdEnv = new Hashtable<String, String>();
pdEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
pdEnv.put(Context.PROVIDER_URL, "iiop://localhost:2810");
Context initialContext = new InitialContext(pdEnv);
DataSource datasource = (DataSource) initialContext.lookup("testDS");
if (datasource != null) {
connection = datasource.getConnection("admin","admin"); // DB credintials
} else {
LOGGER.info("Failed to lookup datasource.");
}
Note: I created the data source in websphere(Version 7) and the JNDI name is testDS
and we have to add com.ibm.ws.ejb.thinclient_7.0.0.jar jar in the class path.
Thanks Sean F and PhilipJ for your support regarding this issue.
DataSource dataSource = (DataSource) initialContext
.lookup("jdbc/oracleDS");
try this way.
look here

how to deploy java web application with mysql database on tomcat server

I have created java web application in eclipse with database mysql.But now i have to deploy that web application in tomcat server.I know how to deploy web application without databas but need assistance with database.
Thank you in advance.
There are two main ways to obtain JDBC connections within a Java Web Application.
Retrieve a connection from a DataSource registered in a JNDI directory service within the container.
Creating a Connection manually within your application code.
JNDI
Using JNDI requires a connection pool to be created within tomcat. This can be done within the context.xml file in tomcat's config directory.
Example Context.xml Entry
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="dbusername"
password="dbpassword"
driverClassName="org.hsql.jdbcDriver"
url="jdbc:HypersonicSQL:database"
maxActive="8"
maxIdle="4"/>
This connection would then be retrieved in your code as follows:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
envCtx.lookup("jdbc/EmployeeDB");
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();
Manual Creation
Manually creating the connection within your code is simpler, however JNDI is recommended for its portability.
Manual Example
public class MysqlConnect{
public static void main(String[] args) {
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/";
String dbName = "jdbctutorial";
String driver = "com.mysql.jdbc.Driver";
String userName = "root";
String password = "root";
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url+dbName,userName,password);
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
When deploying for either of these scenarios it is important that you have the appropriate JDBC driver in your classpath.
There are 2 scenarios here:
You define the connection directly in the code using simple JDBC and Class.forName() - in that case you just need to make sure the jar containing the driver is in the classpath and it should work.
This is the preferred method - Define a Datasource on the server and call it in the code by using the JNDI API:
InitialContext ic = new InitialContext();
DataSource ds = (DataSource)ic.lookup("jdbc/testDS");
conn = ds.getConnection();
in contex.xml using -- tag we can connect to any db

can't get DB Connection using JNDI datasource on JBoss

I'm studying how to build java webapps for JBossAS 5.1.0 and I'm trying to build a very basic jsp web app on JBossAS5 using a JNDI datasource for data access.
When trying to open a connection I get this exception:
21:42:52,834 ERROR [STDERR] Cannot get connection: org.jboss.util.NestedSQLException:
Unable to get managed connection for hedgehogDB; - nested throwable:
(javax.resource.ResourceException: Unable to get managed connection for hedgehogDB)
The datasource is deployed ok, I can see it in the jmx-console & the database files are getting created ok.
Java code in question where the exception is thrown:
static public Connection getHedgehogConnection()
{
Connection result = null;
try
{
String DS_Context = "java:comp/env/jdbc/hedgehogDB";
Context initialContext = new InitialContext();
if ( initialContext == null)
log("JNDI problem. Cannot get InitialContext.");
DataSource datasource = (DataSource)initialContext.lookup(DS_Context);
if (datasource != null)
result = datasource.getConnection();
else
log("Failed: datasource was null");
}
catch(Exception ex)
{
log("Cannot get connection: " + ex);
}
return result;
}
web.xml:
<web-app>
<resource-ref>
<res-ref-name>jdbc/hedgehogDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
jboss-web.xml:
<jboss-web>
<resource-ref>
<res-ref-name>jdbc/hedgehogDB</res-ref-name>
<jndi-name>java:/hedgehogDB</jndi-name>
</resource-ref>
</jboss-web>
hedgehogdb-ds.xml
<datasources>
<local-tx-datasource>
<jndi-name>hedgehogDB</jndi-name>
<connection-url>jdbc:hsqldb:${jboss.server.data.dir}${/}hypersonic${/}hedgehogDB</connection-url>
<driver-class>org.hsqldb.jdbcDriver</driver-class>
<user-name>sa</user-name>
<password></password>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
<idle-timeout-minutes>0</idle-timeout-minutes>
<track-statements/>
<security-domain>HsqlDbRealm</security-domain>
<prepared-statement-cache-size>32</prepared-statement-cache-size>
<metadata>
<type-mapping>Hypersonic SQL</type-mapping>
</metadata>
<depends>jboss:service=Hypersonic,database=hedgehogDB</depends>
</local-tx-datasource>
<mbean code="org.jboss.jdbc.HypersonicDatabase"
name="jboss:service=Hypersonic,database=hedgehogDB">
<attribute name="Database">hedgehogDB</attribute>
<attribute name="InProcessMode">true</attribute>
</mbean>
</datasources>
This is my first time in this environment and I suspect that I'm missing something really basic.
it's also possible to in -ds.xml use < application-managed-security / > instead of < security-domain >, at lease in Jboss6
Looking at your code, it appears that you get the DataSource correctly -- otherwise it would be null. So the problem happens when you try to get the connection.
Looking at the HSQLDB docs, it seems that your URL needs a "file" component:
jdbc:hsqldb:file:${jboss.server.data.dir}${/}hypersonic${/}hedgehogDB
And, as a general coding comment, (1) use a standard logging package, rather than a homegrown "log" method, and (2) when logging an exception, use the logger call (supported by both Log4J and Commons Logging, probably others) that takes an exception as a paramter (so that you get the full stack trace).
Figured it out:
The culprit was this in hedgehogdb-ds.xml :
<security-domain>HsqlDbRealm</security-domain>
HsqlDbRealm was configured for a different DS & was causing the connection to fail.

Categories

Resources