How to lookup JNDI resources on WebLogic? - weblogic

I deployed a legacy application on WebLogic 11g. The application has the following code:
Context context = new InitialContext();
dataSource = (javax.sql.DataSource) context.lookup("java:myDataSource");
I also have a data source configured in WebLogic with the JNDI name of:
jdbc/myDataSource
When the above java code runs, I get the following exception:
javax.naming.NameNotFoundException: While trying to look up /myDataSource in /app/webapp/axis2.war/60105275.; remaining name '/myDataSource'
at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1139)
at weblogic.jndi.internal.ApplicationNamingNode.lookup(ApplicationNamingNode.java:144)
I'm fairly new to JNDI, so my question is? Where is the disconnect in naming? What does it mean when a context lookup has a prefix of "java:" ?
Thanks!

You should be able to simply do this:
Context context = new InitialContext();
dataSource = (javax.sql.DataSource) context.lookup("jdbc/myDataSource");
If you are looking it up from a remote destination you need to use the WL initial context factory like this:
Hashtable<String, String> h = new Hashtable<String, String>(7);
h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL, pURL); //For example "t3://127.0.0.1:7001"
h.put(Context.SECURITY_PRINCIPAL, pUsername);
h.put(Context.SECURITY_CREDENTIALS, pPassword);
InitialContext context = new InitialContext(h);
dataSource = (javax.sql.DataSource) context.lookup("jdbc/myDataSource");
weblogic.jndi.WLInitialContextFactory

java is the root JNDI namespace for resources. What the original snippet of code means is that the container the application was initially deployed in did not apply any additional namespaces to the JNDI context you retrieved (as an example, Tomcat automatically adds all resources to the namespace comp/env, so you would have to do dataSource = (javax.sql.DataSource) context.lookup("java:comp/env/jdbc/myDataSource"); if the resource reference name is jdbc/myDataSource).
To avoid having to change your legacy code I think if you register the datasource with the name myDataSource (remove the jdbc/) you should be fine. Let me know if that works.

I had a similar problem to this one. It got solved by deleting the java:comp/env/ prefix and using jdbc/myDataSource in the context lookup. Just as someone pointed out in the comments.

I just had to update legacy Weblogic 8 app to use a data-source instead of hard-coded JDBC string.
Datasource JNDI name on the configuration tab in the Weblogic admin showed: "weblogic.jdbc.ESdatasource", below are two ways that worked:
Context ctx = new InitialContext();
DataSource dataSource;
try {
dataSource = (DataSource) ctx.lookup("weblogic.jdbc.ESdatasource");
response.getWriter().println("A " +dataSource);
}catch(Exception e) {
response.getWriter().println("A " + e.getMessage() + e.getCause());
}
//or
try {
dataSource = (DataSource) ctx.lookup("weblogic/jdbc/ESdatasource");
response.getWriter().println("F "+dataSource);
}catch(Exception e) {
response.getWriter().println("F " + e.getMessage() + e.getCause());
}
//use your datasource
conn = datasource.getConnection();
That's all folks. No passwords and initial context factory needed from the inside of Weblogic app.

Related

One-Way sync of data without changing schema of source database

I Have a database that we want to partially sync data out of into another database (on Azure).
I have been looking at Sync Framework 2.1 and believe it can solve the problem, however i cannot figure it out from the online documentation.
We have the restraint that we cannot change the schema of the database however we are on SQL 2008 R2 which means that we can use track changes.
I am looking for some advise on how this might be achieved.
currently i have a SyncOrchestrator
var orch = new SyncOrchestrator
{
LocalProvider = new SampleServerSyncProvider(),
RemoteProvider = new SampleClientSymcProvider(),
Direction = SyncDirectionOrder.Upload
};
and then a sync provider
public class SampleServerSyncProvider : DbServerSyncProvider
{
private String SQLLocalConnection = "valid connection string";
public SampleServerSyncProvider()
{
SqlConnection serverConn = new SqlConnection(SQLLocalConnection);
Connection = serverConn;
Connection.Open();
var cmTableSyncAdapter = new SqlSyncAdapterBuilder
{
Connection = serverConn,
ChangeTrackingType = ChangeTrackingType.SqlServerChangeTracking,
SyncDirection = SyncDirection.Bidirectional,
TableName = "my table"
};
SyncAdapters.Add(cmTableSyncAdapter.ToSyncAdapter());
}
}
Currently i am getting an error that talks about initializing the connection. But I cannot find an initialize method on any of the objects
System.InvalidOperationException : Cannot create a SyncAdapter for table 'My table' by using
SqlSyncAdapterBuilder because the connection to the server has not yet
been initialized. Initialize the Connection property of the
SqlSyncAdapterBuilder before you call any of the SqlSyncAdapterBuilder
methods
SQL Change Tracking is only supported on the older offline providers (SqlClientSyncProvider/DbServerSyncProvider/SyncAgent). The newer providers you're trying to use (SqlSyncProvider/SyncOrchestrator) requires a custom change tracking. You cannot mix and match the database sync providers.
have you looked at using SSIS instead?

How to manipulate LDAP using JNDI on websphere?

I am facing a problem with an LDAP operation. I want to dynamically add a member to an LDAP group when selected by the user from GUI / browser. I paste the code below which works perfectly well when I run it in a Test class (using com.sun.jndi.ldap.LdapCtxFactory). But, when I package it in my build, deploy on websphere app server 7.0 (using com.ibm.websphere.naming.WsnInitialContextFactory), and invoke this method according to user's selection, then I get the error below. I wonder what's wrong I am doing. Doesn't WAS provide implementation of ldap connection factory? I also tried deploying on WAS with the sun's ldap which otherwise works on the Test class, but I am getting the same exception as below. I'd appreciate if anybody can give a clue.
Problem adding member: javax.naming.OperationNotSupportedException: [LDAP: error code 53 - 00000561: SvcErr: DSID-031A120C, problem 5003 (WILL_NOT_PERFORM), data 0
My Code:
public class LDAPManager
{
String GROUPS_OU = "cn=users,dc=mit,dc=hq,dc=com";
public Boolean addMember(String user, String group)
{
Hashtable env = new Hashtable();
String adminName = "CN=Administrator,CN=Users,DC=mit,DC=hq,DC=com";
String adminPassword = "asdfasdf21Q";
String ldapURL = "ldap://mybox451Dev.mit.hq.com:389";
String userName = "CN="+user+",CN=Users,DC=mit,DC=hq,DC=com";
String groupName = "CN="+group+",CN=Users,DC=mit,DC=hq,DC=com";
//env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
//set security credentials, note using simple cleartext authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,adminName);
env.put(Context.SECURITY_CREDENTIALS,adminPassword);
//connect to my domain controller
env.put(Context.PROVIDER_URL, "ldap://mybox451Dev.mit.hq.com:389");
try {
// Create the initial directory context
InitialDirContext ctx = new InitialDirContext(env);
//Create a LDAP add attribute for the member attribute
ModificationItem mods[] = new ModificationItem[1];
mods[0]= new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("member", userName));
//update the group
ctx.modifyAttributes(groupName,mods);
ctx.close();
//System.out.println("Added " + userName + " to " + groupName);
}
catch (NamingException e) {
System.err.println("Problem adding member: " + e);
}
return true;
}
}
I got it solved. Posting solution here, hope this helps someone.
Use the standard JNDI context of sun, not websphere.
Additional properties I was missing in the hashtable, once I added them, it worked like a charm.
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
//env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
//set security credentials, note using simple cleartext authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,adminName);
env.put(Context.SECURITY_CREDENTIALS,adminPassword);
env.put(Context.URL_PKG_PREFIXES, "com.sun.jndi.url");
env.put(Context.REFERRAL, "ignore");
Well, it's been more than a year since this question has been asked; so, I don't know answering will add any value. But, here it is. See WAS Javadocs for details on how what that factory class actually does and how it works. You may need to adjust your jndiprovider.properties file for WAS.

Access remote objects with an RMI client by creating an initial context and performing a lookup

I'm trying to look up the PublicRepository class from an EJB on a Weblogic 10 server. This is the piece of code:
/**
* RMI/IIOP clients should use this narrow function
*/
private static Object narrow(Object ref, Class c) {
return PortableRemoteObject.narrow(ref, c);
}
/**
* Lookup the EJBs home in the JNDI tree
*/
private static PublicRepository lookupHome() throws NamingException {
// Lookup the beans home using JNDI
Context ctx = getInitialContext();
try {
Object home = ctx.lookup("cea");
return (PublicRepository) narrow(home, PublicRepository.class);
} catch(NamingException ne) {
System.out.println("The client was unable to lookup the EJBHome. Please make sure ");
System.out.println("that you have deployed the ejb with the JNDI name "
+ "cea" + " on the WebLogic server at " + "iiop://localhost:7001");
throw ne;
}
}
private static Context getInitialContext() throws NamingException {
try {
// Get an InitialContext
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL, "iiop://localhost:7001");
return new InitialContext(h);
} catch(NamingException ne) {
System.out.println("We were unable to get a connection to the WebLogic server at " + "iiop://localhost:7001");
System.out.println("Please make sure that the server is running.");
throw ne;
}
}
I'm however getting Cast Exception:
Exception in thread "main" java.lang.ClassCastException
at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(Unknown Source)
at javax.rmi.PortableRemoteObject.narrow(Unknown Source)
at vrd.narrow(vrd.java:67)
at vrd.lookupHome(vrd.java:80)
at vrd.main(vrd.java:34)
Caused by: java.lang.ClassCastException: weblogic.corba.j2ee.naming.ContextImpl
... 5 more
Am I correct when I'm using the above code to retrive a certain class to be used in my client application? How could I get rid of the cast exception?
The simple thing to do would be to store the result of 'narrow' in a java.lang.Object and then see what type it is...
The error means you've looked up a Context rather than a bound object. In other words, you looked up "cea" instead of something like "cea/Bean". It's the analogous to using a FileInputStream on a directory.
I was using the wrong JNDI name, hence it couldn't retrieve the object. Thanks everyone for looking.

Using JNDI to access a DataSource (Tomcat 6)

I have been trying to set up a Database Connection Pool for my test webapp just to learn how it's done really. I have managed to get a DataSource object connected to my database which supplies me with Connection objects now, so that's good.
I must admit I don't really know exactly how it's working. I wrote some test code to see if I could figure out how the InitialContext object is working:
package twittersearch.web;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import twittersearch.model.*;
public class ContextTest extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
Context ctx = null;
Context env = null;
try {
ctx = new InitialContext();
Hashtable<?, ?> h = ctx.getEnvironment();
Enumeration<?> keyEn = h.keys();
while(keyEn.hasMoreElements()) {
Object o = keyEn.nextElement();
System.out.println(o);
}
Enumeration<?> valEn = h.elements();
while(valEn.hasMoreElements()) {
Object o = valEn.nextElement();
System.out.println(o);
}
env = (Context)ctx.lookup("java:comp/env");
h = env.getEnvironment();
Enumeration<?> keys = h.keys();
Enumeration<?> values = h.elements();
System.out.println("Keys:");
while(keys.hasMoreElements()) {
System.out.println(keys.nextElement());
}
System.out.println("Values:");
while(values.hasMoreElements()) {
System.out.println(values.nextElement());
}
Collection<?> col = h.values();
for(Object o : col) {
System.out.println(o);
}
DataSource dataSource = (DataSource)env.lookup("jdbc/twittersearchdb");
Connection conn = dataSource.getConnection();
if(conn instanceof Connection) {
System.out.println("Have a connection from the pool");
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
This gives me output of:
java.naming.factory.initial
java.naming.factory.url.pkgs
org.apache.naming.java.javaURLContextFactory
org.apache.naming
Have a connection from the pool
Keys:
Values:
Have a connection from the pool
What I don't understand
I have got the InitialContext object which, as I understand it, I should be able to get a Hashtable from with keys and values of all the bindings for that context. As the first four lines of the output show, there were only two bindings.Yet I am able to use ctx.lookup("java:comp/env") to get another context that has bindings for Resources for my webapp. There was no "java:comp/env" in the keys from the test output from the InitialContext object. Where did that come from?
Also as you can see I tried to printout the keys and values from the java:comp/env context and got no output and yet I am able to use env.lookup("jdbc/twittersearchdb") which gets me the DataSource that I have specified in my context.xml. Why do I have no output for the bindings for the "java:comp/env" context?
Can I just confirm that as I have specified a Resource element in my context.xml, the container is creating a DataSource onject on deployment of the webapp and the whole Context / InitialContext thing is just a way of using JNDI to access the DataSource object? And if that's the case, why is JNDI used when it seems easier to me to create a DataSource in an implementation of ServletContextListener and have the datasource as a ServletContext attribute?
Does the DataSource object actually manage the ConnectionPool or is that the Container and so is the DataSource object just a way of describing the connection?
How do we access the container directly? What is the object that acctually represents the container? Is it ServletContext? I'm just trying to find out what the container can do for me.
Apologies for the length of this post. I really want to clear up these issues because I'm sure all this stuff is used in every webapp so I need to have it sorted.
Many thanks in advance
Joe

How to deploy a Configuration to the JNDI tree of the Glass fish server

I want to deploy a HashMap of configuration to the JNDI tree of Glass Fish server. I am migrating a framework from Weblogic to GLassfish. Previously it was done via the following code..
Where the Environment is weblogic.jndi.Environment;
public void deployConfiguration(HashMap configuration)
throws GenericFrameworkException {
Context ictx = null;
String configParameter = null;
Environment env = new Environment();
env.setReplicateBindings(false);
// get the NOT replicating initial context of this server
ictx = ServiceLocator.getNotReplicatingInitialContext();
if (ictx != null) {
Set e = configuration.keySet();
Iterator iter = e.iterator();
while (iter.hasNext()) {
configParameter = (String) iter.next();
this.addParameter(
ictx,
Constants.JNDI_SUB_PATH,
configParameter,
configuration.get(configParameter));
}
}
}
Can any one suggest how this can be achieved in Glassfish
Thanks in Advance.
It seems as if you are looking for custom jndi resources:
http://docs.oracle.com/cd/E26576_01/doc.312/e24930/jndi.htm#beanz