How do I lookup a JNDI Datasource from outside a web container
Jumat, 07 Juni 2013
0
komentar
Another interesting request from different project.
Problem : While doing the UnitTesting, team was not able to execute their unit tests outside Web/App container[IBM Websphere]. Couple of issues, and out of which the main issues were -
# The classpath problem as most of the libraries and other projects were not visible with JUnit Cases / Projects.
# JNDI lookup failed especially for Datasource connection.
Solution -
Classpath issues can be solved without much effort and its more or less depends on specific project configuration. One way is to add something below to the ".classpath" file of the JUnit project.
<classpathentry kind="lib" path="C:/WSAD/MyJUnitProject/lib"/>
Am more curious to discuss the solution for JNDI lookup. There are multiple solutions I feel, let me explain one by one, and finally my favorite.
Properties prop = new Properties();
prop.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
prop.put(Context.PROVIDER_URL,"iiop://localhost:2811"); <Or 2809, the standard port>
InitialContext init = new InitialContext(prop);
DataSource ds = (DataSource) init.lookup("jdbc/testDS");
Solution 0: JNDI Lookup issue
Step 0 : Added the code mentioned in the following link. This has been updated in BaseTest.setUp() method.
Hashtable<Object, Object> env = new Hashtable<Object, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
env.put(Context.PROVIDER_URL, "iiop://localhost:8998"); // corbaloc:iiop:localhost:8998
Context initialContext = new InitialContext(env);
// InitialContext ic = BeanHelper.getInitialContext();
System.out.println("******** setting InitialContext");
initialContext.createSubcontext("java:");
initialContext.createSubcontext("java:/comp");
initialContext.createSubcontext("java:/comp/env");
initialContext.createSubcontext("java:/comp/env/jdbc");
initialContext.createSubcontext("java:/comp/env/jdbc/MyDataSource");
Step 1 : Added the following Jars in the classpath -> naming.jar, namingclient.jar
Step 2 : Added the DB2 DataSource classes/JARs -> db2jcc.jar, db2jcc_license_cu.jar, db2policy.jar
Step 3 : Make sure the JRE is from IBM Websphere.
Step 4 : Bind the ConnectionPoolDataSource with the JNDI context.
DB2ConnectionPoolDataSource ds = new com.ibm.db2.jcc.DB2ConnectionPoolDataSource();
ds.setServerName("SERVERNAME");
ds.setDataSourceName("DATASOURCE");
ds.setDatabaseName("DBNAME");
ds.setPortNumber(40408);
ds.setUser("USERID");
ds.setPassword("PASSWORD");
initialContext.bind("java:/comp/env/jdbc/IOIDataSource", ds);
Step 5 : Adding thin clients :
Include the thinclient-jars to your buildpath. You will need them to do a jndi lookup from a standalone client.
%WAS_HOME%/runtimes is where they can be found.
Step 6 : Add com.ibm.ws.admin.client_7.0.0.jar from runtime
Solution 1 : With apache libraries
Step 0 : Change the Context.INITIAL_CONTEXT_FACTORY to "org.apache.naming.java.javaURLContextFactory"
Step 1 : properties.put("java.naming.corba.orb",org.omg.CORBA.ORB.init(new String[] {}, null));
Step 2 : Add two apache libraries, available in Tomcat.
Step 3 : Update JNDI lookup to J2EE standard -> java:comp/env/jdbc/MyDataSource
Step 4 : Add the dependency libraries - juli-6.0.18.jar and catalina.jar
Solution 2 :
# Create the JUnitLocalDataSource, we can extend any Datasource implementation
public class JUnitLocalDataSource extends DB2DataSource{
private String serverName = "SERVERNAME";
private String dataSourceName = "DS_SOURCE";
private String databaseName = "DBNAME";
private int portNumber = 40408;
private String user = "USER";
private String password = "PASSWORD";
public JUnitLocalDataSource(){
System.out.println("******** configuring DB2ConnectionPoolDataSource");
setServerName(serverName);
setDataSourceName(dataSourceName);
setDatabaseName(databaseName);
setPortNumber(portNumber);
setUser(user);
setPassword(password);
}
public JUnitLocalDataSource(String serverName, String dataSourceName, String databaseName, int portNumber, String user, String password ){
setServerName(serverName);
setDataSourceName(dataSourceName);
setDatabaseName(databaseName);
setPortNumber(portNumber);
setUser(user);
setPassword(password);
}
# Create JUnitContextFactory class.
public class JUnitContextFactory implements InitialContextFactory, InitialContextFactoryBuilder {
private static JUnitContextFactory jUnitContextFactory = null;
public JUnitContextFactory() throws NamingException{
super();
}
public JUnitContextFactory(Hashtable<?, ?> envmt) throws NamingException{
super();
}
public InitialContext getInitialContext(Hashtable<?, ?> environment) throws NamingException {
LocalContext localContext = null;
try{
localContext = new LocalContext(environment);
NamingManager.setInitialContextFactoryBuilder(this);
}catch(Exception exception){
exception.printStackTrace();
}
return pliContext;
}
@Override
public InitialContextFactory createInitialContextFactory(
Hashtable<?, ?> envmt) throws NamingException {
if(jUnitContextFactory == null){
jUnitContextFactory = new JUnitContextFactory();
}
return jUnitContextFactory;
}
}
# Create LocalContext class
public class UserContext extends InitialContext {
private static DataSource localDataSource;
private static Properties prop = new Properties();
private LocalContext(Properties properties) throws NamingException {
super(properties);
loadLocalDataSource();
}
public PLIContext(Hashtable<?, ?> properties) throws NamingException {
super();
loadLocalDataSource();
}
public void loadLocalDataSource(){
try {
if(localDataSource == null || localDataSource.getConnection() == null){
localDataSource = new JUnitLocalDataSource();
prop.put("jdbc/IOIDataSource", localDataSource);
prop.put("java:comp/env/jdbc/MyDataSource", localDataSource);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public Object lookup(String name) throws NamingException {
try {
Object value = prop.get(name);
return (value != null) ? value : super.lookup(name);
}
catch(Exception e) {
e.printStackTrace();
}
return name;
}
}
# Add the following code to the "setUp()" method of the BaseUnitTest class or wherever required.
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.pru.JUnitContextFactory");
properties.put(Context.PROVIDER_URL, "iiop://localhost:2809");
properties.put("java.naming.corba.orb",org.omg.CORBA.ORB.init(new String[] {}, null));
JUnitContextFactory contextFactory = new JUnitContextFactory();
InitialContext iniCtx = contextFactory.getInitialContext(properties);
We can optimise these classes, or combine all these into single class, which am leaving to you to explore. Enjoy coding.
TERIMA KASIH ATAS KUNJUNGAN SAUDARA
Judul: How do I lookup a JNDI Datasource from outside a web container
Ditulis oleh Unknown
Rating Blog 5 dari 5
Semoga artikel ini bermanfaat bagi saudara. Jika ingin mengutip, baik itu sebagian atau keseluruhan dari isi artikel ini harap menyertakan link dofollow ke http://apk-zipalign.blogspot.com/2013/06/how-do-i-lookup-jndi-datasource-from.html. Terima kasih sudah singgah membaca artikel ini.Ditulis oleh Unknown
Rating Blog 5 dari 5
0 komentar:
Posting Komentar