http://localhost:8080/rtsclient/loginform.faces
Url jnp://localhost:1099
Application Server Type jboss40
Datasource jdbc/ilogDataSource
User rtsAdmin
Password rtsAdmin
The above is for jboss.
Now i have deployed RTS onto Sun Application Server. And i want to configure the jndi such that.
My RTS client can actually access it.
How do i go about this?
I asked this question here
http://forums.ilog.com/brms/index.php?topic=803.0
i know it is quite specific.
But how to do it generally in sun application server?
I think creating a jndi.properties file in your project root with the following should be enough.
org.omg.CORBA.ORBInitialHost=localhost
org.omg.CORBA.ORBInitialPort=1099
java.naming.security.principal=rtsAdmin
java.naming.security.credentials=rtsAdmin
There are also a few other things configurable if you need to
java.naming.provider.url=...
java.naming.factory.initial=...
java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory
java.naming.factory.url.pkgs=com.sun.enterprise.naming
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl
A less flexible method is also available. On startup provide the needed values to the InitialContext()-constructor as a Hashmap
Properties prop = new Properties();
prop.put(Context. ...., "...");
e.g.
prop.put(Context.SECURITY_PRINCIPAL, "rtsAdmin");
prop.put(Context.SECURITY_CREDENTIALS, "rtsAdmin");
InitialContext context = new InitialContext(prop);
Check here what you can set via the constructor
Related
I am developed a service that use the DataSource from a local JNDI (Server where to live the service and the JNDI).
In Spring boot this information is declared like this:
spring: datasource:
jndi-name: java:/comp/env/jdbc/MyLocalDB
I want to know if is possible to do something like this:
spring: datasource:
jndi-name: java:192.168.0.1:8080/comp/env/jdbc/MyLocalDB
Thanks
JNDI is an API to access directories. Application servers include directories to maintain information of the applications, the datasources and the EJB beans. JNDI can be used to access other types of directories. For instance, it can be used to access user information on Active Directoy and LDAP directory servers.
You can create client programs that access these JNDI directories and obtain data such as configuration data and RMI remote references to invoke EJB beans.
Accessing remote JNDI directories
If you are creating a client program, you can define an InitialContext describing the JNDI directory your program will use. You must define a Hashtable with the configuration, defining a Context.PROVIDER_URL and create the InitialContext.
For instance, you can create a program that access information in an LDAP directory.
// Set up the environment for creating the initial context
Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");
// Create the initial context
DirContext ctx = new InitialDirContext(env);
// ... do something useful with ctx
Depending on the library you use, you can define a configuration file describing the JNDI remote host. For instance, for the JBoss EJB Client library, you can define a jboss-ejb-client.propertiesfile. Glassfish uses a jndi.properties file.
Accessing remote resources
A resource is data (e.g an image, audio, or text) that a program needs to access independently of the location of the program code. You can use the JNDI API or the #Resource annotation to access the information.
For instance, you can use the API to ask for data of users in an LDAP directory.
try {
// Create the initial directory context
DirContext ctx = new InitialDirContext(env);
// Ask for all attributes of the object
Attributes attrs = ctx.getAttributes("cn=Ted Geisel, ou=People");
// Find the surname attribute ("sn") and print it
System.out.println("sn: " + attrs.get("sn").get());
} catch (NamingException e) {
System.err.println("Problem getting attribute:" + e);
}
Accessing remote EJBs
You can access EJBs with remote interfaces located in other VMs. On the one hand, you must create the EJBs using CORBA-style remote interfaces and register the EJBs in the java: namespace in the server. On the other hand, the applications can use a corbaname URL to access these beans.
In Websphere/Liberty, if you define an EJB bound to:
java:global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface
java:app/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface
java:module/ExampleBean!com.ibm.example.ExampleRemoteInterface
You can access remotely the EJB using RMI-IIOP (to invoke methods)
corbaname::test.ibm.com:2809#ejb/global/ExampleApp/ExampleModule/ExampleHomeBean!com.ibm.example.ExampleEJBHome
corbaname:rir:#ejb/global/ExampleApp/ExampleModule/ExampleHomeBean!com.ibm.example.ExampleEJBHome
Detailed configuration of these remote EJBs may vary from one application server to another. If you use Glassfish, you can check the documentation. There is an example in the Oracle blogs.
If you configure a cluster, there are many other options to access the remote resources using the names of the nodes in the cluster.
Accessing a remote Datasources
Datasources defined in a server cannot be accessed remotely. If you want to keep the configuration of the datasources in the JNDI directory, you can solutions define a custom class that implements the DataSource interface. A client can obtain the datasource configuration from the server and create a local database connection using that connection.
In java EE, the way you get an EJB from a remote server is by looking it up in JNDI. The specification defines the JNDI name for a given bean type.
However, this seems to be only if you want to get a bean off your local computer. I want to get the bean off a remote server, like most users would. How do I specify the server URL? Do I pass a map to the InitialContext constructor?
Note: There is another question that is pretty much the same, but that has become out of date since the definition of portable JNDI names by the specification.
I want to get the bean off a remote server
Yes, you need specify the IP/port where the remote server (JNDI service) is running/listening.
How do I specify the server URL?
You have to set the propertie: java.naming.provider.url and make it available to the InitialConetxt.
This can be done in different ways:
to use a jndi.properties file
to use system properties
passing the value in a Hashtable when you create a new instance of
InitialContext object.
The concrete value of this and others necessary properties to instantiate the InitialConetct are vendor dependen.
An example for JBoss could be:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://yourServer:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
Keep in mind that there is no way that you can get the EJB's stub from a remote server if you donĀ“t indicate the url.
By "Remote" I mean the client and the server are running in different JVM.
You do JNDI lookups of remote EJBs using exactly the same code as you would use when running server-side:
Context context = new InitialContext(); // No properties needed
MyEJB myEjbInstance = (MyEJB) context.lookup("ejb/MyEJB");
Or, of course, you can inject it:
#EJB
private MyEJB myEjbInstance;
To make the naming context work, you must run your application as a Java EE application client. An application client is exactly like a regular standalone Java program, with a standard main method; the only difference is that it needs to be run in a different manner. That manner is not specified in the Java EE Spec, so each application server has its own way of doing it.
GlassFish, for example, requires an application client to include some special jars in the classpath, and set a couple system properties. Specifically, you must include lib/gf-installer.jar and all the jars referenced by its manifest in your classpath, and you must set the org.omg.CORBA.ORBInitialHost and org.omg.CORBA.ORBInitialPort system properties.
I have some code that I want to make public. The code sends email via servers, connects to databases, and other tasks requiring usernames/passwords.
I'd like to store the passwords and such in a seperate configuration file so that I don't have to sanitize my code on every commit.
How can I do this? It would be easy to do in C using #define, but I'm not sure how to accomplish this in Java.
EDIT: The environment I'm using is Glassfish
The basic method is put the information in a properties file and use the Properties class to load it at run time. If you're using a J2EE server, database connections are configured in the server and the code references them by an abstract name.
I think I should add that if you're using a server, how to configure it and how to get the connections to your code will vary by server and J2EE level so post your environment. Using the Properties class is pretty obvious just by looking at the javadoc and the load() methods.
In glassfish, go to the admin console and under Resources create a new connection pool. That defines your database connection and will share a pool of those connections among your applications. Now under JDBC Resources, create a new entry that maps that pool to a name. The name is usually something like jdbc/myappname.
For a J2EE5 or later application, you can now add this as a class level variable:
#Resource(mappedName="jdbc/myappname") DataSource myDS;
At runtime the server will inject that resource to your database pool. Then when you need a connection, you can do this inside any method:
Connection conn = myDS.getConnection();
The result is your code doesn't have to care at all about the database connection information or managing a pool of connections. You can deploy the identical code on development and production servers, and they will get an appropriate connection. In order to get the injection, it has to be a class the server creates like an EJB, servlet, tag library handler, or JSF managed bean.
I am using the com.sun.jndi.fscontext.RefFSContextFactory file based JNDI context factory. It seems to take the drive of the where the java application is started in.
Hashtable properties = new Hashtable(2);
properties.put(Context.PROVIDER_URL,"file:///tmp/jms/mycontext");
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
InitialContext ctx = new InitialContext(properties);
How can I specify the drive letter such as d:/tmp/jms/mycontext ?
Using file://d:/tmp/jms/mycontext seems to still go to the c drive on my system
After some troubleshooting and debugging myself I figured it out. Using an extra \ before the drive letter solves it
properties.put(Context.PROVIDER_URL,"file://\\d:\\tmp\\mycontext");
Like so:
"file:D:\\tmp\\jms\\mycontext"
There are some examples in a tutorial at developerWorks that may be useful:
IBM WebSphere Developer Technical Journal: Running a standalone Java application on WebSphere MQ V6.0
"file:///D:/temp" worked for me
I have a .properties file in my application which contains dataSource properties.
I set up a JNDI reference to this dataSource using the following code :
// first I create MyDataSource from the properties found in the .properties file
//then :
Context initContext = new InitialContext();
initContext.createSubcontext("jdbc");
initContext.createSubcontext("jdbc/oracle");
initContext.rebind(jdbc/oracle/myDataSource, MyDataSource);
If I use a lookup in this application, the dataSource is found :
Context initContext = new InitialContext();
BasicDataSource dataSource =
(BasicDataSource) initContext.lookup("jdbc/oracle/myDataSource")
//everything works fine and I can use my dataSource to getConnection,
//requests, etc...
Now I would like to use this dataSource in another application. But if I do the same lookup than previously, I don't find myDataSource (whereas there is still the previous application in tomcat and the jndi binding is done on start-up with the help of a listener).
How can I get myDataSource in this second application, given that I can't use a Tomcat's resource in server.xml or a context.xml file (for different reasons I have to use this .properties file)?
Thanks
"local" JDNI directories are read-only in Tomcat. Nevertheless, you can bind "global" JNDI resources in a LifecycleListener, and then "link" them to your context(s)(*):
You need to implement org.apache.catalina.LifecycleListener http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/LifecycleListener.html
Then register it in your server.xml like this (along with the other listeners):
<Listener className="yourlistener.YourLifecycleListener"/>
Your listener should await for 2 events:
public void lifecycleEvent(final LifecycleEvent event) {
if (Lifecycle.START_EVENT.equals(event.getType())) {
// Create your datasource instance...
Context initContext = new InitialContext();
initContext.createSubcontext("jdbc");
initContext.createSubcontext("jdbc/oracle");
initContext.rebind("jdbc/oracle/myDataSource", myDataSource);
} else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
// unbind...
}
}
Then you'll have to propagate resource accesses by "linking" them from "global" JNDI directory to "local" JNDI directory using ResourceLink element in your META-INF/context.xml:
<ResourceLink name="jdbc/oracle/myDataSource" global="jdbc/oracle/myDataSource"
type="javax.sql.DataSource" />
That worked for me so far.
(*) Some notes:
There's an advantage on using lifecycle listeners. Since the order of context creation is not guaranteed. The advantage is that all of your contexts will see this object created.
If you need to create and configure datasource creation more dynamically that on lifecycle listener creation, note that you can bind a custom class implementing the Factory pattern.
To avoid classloading incompatibility problems, consider putting your listener, datasource, etc. classes in a jar file in the Tomcat lib directory, so they're included y the common classloader.
Regards.
What you are trying to do is not going to work. J2EE applications are not allowed to modify the JNDI environment provided by the application server (J2EE spec, section 5.2.2) and the Tomcat JNDI documentation also states, that each web applications gets each own read-only JNDI environment. I'm not sure why binding/rebinding your datasource is not failing immediately and why it's working within the same web application, but even such application-internal usage of the JNDI environment is undocumented behaviour, which I would not rely on.
A couple people have already commented on this, but I think the answer to your question is: Tomcat has a file called server.xml that you need to use. A good reference I have used before is below:
http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html
Resources defined here will be visible to all apps deployed (if set up correctly). If you set up a JNDI resource in your apps context or web xml file, it should only be available to your app.
JNDI context are private to each webapp. Context created in one app can't be accessed by others.
Try to create an entry in GlobalNamingResources and links in both webapps using <ResourceLink> to see if it works.
I used this setup before to read from both apps but never tried to write from one. So not sure if it will work.
Actually, it is possible to access others JNDI resources, if the servlet implements org.apache.catalina.ContainerServlet. This interface has a org.apache.catalina.Wrapper attribute, that is "populated" by the container itself.
through that, I created a simple application to monitor resources.
BUT, I would like to do that in a listener, so my resource monitor could start when the container starts. Anyone knows a way?