Java Naming and Directory Interface adding self defined objects to directory - jndi

I have been trying to use JNDI to store my own predefined objects with no success. I can get the jdbc object from the InitialContext and gain access to the connection object as shown below
Class.forName("com.mysql.jdbc.Driver");
InitialContext context = new InitialContext();
DataSource dataSource = (DataSource) context
.lookup("jdbc/DataSource");
Now i need to know how to add my own objects to the jndi directory. Also please can you explain the architecture of jndi service

I need to know how to add my own objects to the jndi directory.
Define them as named resources in your Tomcat context.xml, if you're using Tomcat, or the equivalent in whatever your servlet container is. If you mean to do this at runtime, you can't, that's not what it's for.
Also please can you explain the architecture of jndi service
Far too broad a question for StackOverflow. Try the JNDI Tutorial.

Related

How to get and cast JNDI object correctly in Liberty

I have a big problem on getting the correct instance or at least casting the instance I got with JNDI-lookup to correct interface at Web Sphere Liberty (16.0.0.4, running on Java 7, though using Oracle Java 1.8.0_45 in the back, developing on Eclipse Neon.2).
When I start the server and the ear containing the EJB, I get the following notification into the log:
The server is binding the xxx.interfaces.MyLocal interface of the MyEJB enterprise bean in the xxx-ejb.jar module of the xxx-ear application. The binding location is: java:global/xxx/MyEJB!xxx.interfaces.MyLocal
Then I have a web application (ear) which has a service provider (with #Produces) for the previously started ejb-service, which will provide the JNDI resource as injectable (#Inject) for the rest of the application (a bit tricky thing, the main idea is to allow to change the lookup location from configuration file + do some other stuff also). It seems to work correctly for all it is supposed to, but when getting the JNDI-resource, it kind of works but not correctly.
If I put the ejb part as a dependency into my web-module, I can inject it directly (#Inject MyLocal myEjb;).
As the injected resource I get an object with the signature:
EJSMyLocal0SLMyEJB_a4549339#cc5d2cdd
with lookup I get an object with signature (at the same time as the inject):
EJSMyLocal0SLMyEJB_a4549339#cdda36a7
(Not the same instance afaik, but the "type" is correct?)
The injected resource is correctly (automatically of course) cast on 'MyLocal' interface and is ok.
When I try to check the resource got with JNDI, it does not qualify as an instance of 'MyLocal' nor as 'MyRemote'? Also the actual cast fails of course with ClassCastException. (MyRemote is basically the same as the MyLocal interface ... MyLocal extends MyRemote, both interfaces are accordingly annotated with #Local and #Remote)
The EJB looks like this at the time of testing...
#Stateless
#Named
#Default
#Local(MyLocal.class)
#Remote(MyRemote.class)
public class MyEJB implements MyLocal, MyRemote { ... }
I also tried to cast the JNDI resource like this.
InitialContext ic = new InitialContext();
Object lookedUpEjb = ic.lookup(lookup); // the 'java:global...' from log
MyRemote jndiEjb = (MyRemote) PortableRemoteObject.narrow(lookedUpEjb, MyRemote.class)
// Tried also casting/checking 'instanceof' to MyLocal...
No difference with that, the same ClassCastException occurs?!
I have the following features in server.xml
<featureManager>
<feature>javaee-7.0</feature>
<feature>ldapRegistry-3.0</feature>
<feature>localConnector-1.0</feature>
<feature>adminCenter-1.0</feature>
<feature>wsSecurity-1.1</feature>
<feature>ejbLite-3.2</feature>
<feature>ejbRemote-3.2</feature>
<feature>cdi-1.2</feature>
<feature>jpa-2.1</feature>
<feature>jsf-2.2</feature>
<feature>jaxrs-2.0</feature>
<feature>jaxws-2.2</feature>
</featureManager>
I found this documentation on the Liberty JNDI functionality:
https://www.ibm.com/support/knowledgecenter/SSAW57_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/twlp_ejb_remote.html
I can't see where I go wrong. How do I cast that object from JNDI lookup to MyLocal or MyRemote interfaces?
---- Note ----
Using the #EJB annotation is not an option (it works though), since it will be hard coded reference to the resource. I want it to be optional though, thus JNDI lookup. #EJB will cause the app to crash when the resource is not available.
The problem is that each application has a different ClassLoader and the object that has been bound into JNDI was loaded with the ClassLoader of the application that defined the EJB.
This should not be an issue for Remote EJB interfaces as the ORB should have taken care of this for you. On a remote call that returns such an object, the ORB will serialize the object (from the target ClassLoader) and then deserialize using the client ClassLoader. For a lookup like this, the PortableRemoteObject.narrow should also take care of this. The failure here appears to just be a bug in the ORB.
In order to support cross application access to Local EJB interfaces, either the Local EJB interface needs to be moved to a shared library, that is used by both applications, or both applications configured to use a single global ClassLoader. See this link for more information about using Local EJB interfaces across applications: Correct way to lookup local EJB in websphere - Getting ClassCastException (Note: this link is discussing traditional WebSphere, but the issue is the same with Liberty, as is the resolution to use a shared library for the interface).

Connection Pooling with Apache DBCP

I want to use Apache Commons DBCP to enable connection pooling in a Java Application (no container-provided DataSource in this). In many sites of the web -including Apache site- the usage of the library is based in this snippet:
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
ds.setUsername("scott");
ds.setPassword("tiger");
ds.setUrl(connectURI);
Then you get your DB connections through the getConnection() method. But on other sites -and Apache Site also- the Datasource instance is made through this:
ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(connectURI,null);
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory);
ObjectPool objectPool = new GenericObjectPool(poolableConnectionFactory);
PoolingDataSource dataSource = new PoolingDataSource(objectPool);
What's the difference between them? I'm using connection pooling with BasicDataSource, or I need an instance of PoolingDataSource to work with connection pooling? Is BasicDataSource thread-safe (can I use it as a Class attribute) or I need to synchronize its access?
BasicDataSource is everything for basic needs.
It creates internally a PoolableDataSource and an ObjectPool.
PoolableDataSource implements the DataSource interface using a provided ObjectPool. PoolingDataSource take cares of connections and ObjectPool take cares of holding and counting this object.
I would recommend using BasicDataSource.
Only, If you really need something special maybe then you can use PoolingDatasource with another implementation of ObjectPool, but it will be very rare and specific.
BasicDataSource is thread-safe, but you should take care to use appropriate accessors rather than accessing protected fields directly to ensure thread-safety.
This is more of a (big) supporting comment to ivi's answer above, but am posting it as an answer due to the need for adding snapshots.
BasicDataSource is everything for basic needs. It creates internally a
PoolableDataSource and an ObjectPool.
I wanted to look at the code in BasicDataSource to substantiate that statement (which turns out to be true). I hope the following snapshots help future readers.
The following happens when the first time one does a basicDatasource.getConnection(). The first time around the DataSource is created as follows :
This is the raw connectionFactory.
This is the Generic Object Pool ('connectionPool') that is used in the remaining steps.
This combines the above two (connectionFactory + an Object Pool) to create a PoolableConnectionFactory. Significantly, during the creation of the PoolableConnectionFactory, the connectionPool is linked with the connectionFactory like so:
Finally, a PoolingDataSource is created from the connectionPool

can I have 2 different datasources in groovy with different privileges

I was wondering if we can have 2 datasources configured in a Grails application, I want one to have readonly access (select) and the other to have read-write access (create, insert, update..)
For pre-2.0 apps use http://grails.org/plugin/datasources/ and for 2.0 it's built into Grails - see the docs at http://grails.org/doc/2.0.0.RC1/guide/conf.html#multipleDatasources
Yes you can but - from my experience - with some conditions/limitations that you should be aware of.
Know this:
Grails 2 can't login with spring security when using multiple databases
The documentation http://grails.org/doc/2.0.0.RC1/guide/conf.html#multipleDatasources says that you can switch between datasources either via domain mapping or by using services and the static "datasource" property.
I have found that the domain mapping does work, but the services alone does not work and from the way I interpreted the documentation we should be able to do either.
2.1 Define Datasources in Datasources.groovy:
You can declare what datasource you want your domain models to use, that works fine. As well, declare your domain to use several datasources and then specify which datasource to use in your controllers:
bookInstance.db1.save()
or
bookInstance.db2.save()
OR, when the datasource is unknown before hand you can do this:
def ds = "db1" // or set it to anything you want, db1, db2, db3...
bookstance."$ds".save()
BUT, if you want to use services to declare the datasource, that does NOT work at all for me.
static datasource = "db1"
No matter what, this has not worked for me in Grails Services.
2.2 Declare Datasource in the default Database and then inject other datasources at runtime.
The documentation says that you can inject at runtime a new datasource bean. And you can, but it does not get picked up by Grails. I have not been able to get Grails to be aware of the newly injected datasource beans. So, the datasources MUST be pre-declared in Datasource.grooy
-

Spring.Net/Caliburn v2 Dependency hell?

I'm putting a project together with Spring.NET and Caliburn v2. I have some objects that I'm trying to instantiate, but not sure how to go about it.
I have been using Caliburn's IoC aspect annotations (Singleton and PerRequest) to get objects into the Spring context. The problem with this is that I have two objects, A and B, where Object B is a subclass of Object A (meaning B is also an A). This means that if I register both, Spring complains of ambiguity when an object of type A is requested. To get around this, I could stop using Caliburn's IoC aspects to register the objects and instead register them in the Spring context XML files. That way I can specify a named object in the Spring context file to use in the constructor of object C, which needs an object of type B injected.
However, this creates a new problem. Object B needs the Caliburn window manager to be injected (which is not available to the Spring container at the time when the objects listed in the context XML files are instantiated, but only later, after Caliburn has loaded and added its own objects to the Spring container).
I could simply remove the inheritance and let some code duplication occur between objects A and B, but then what would be the point of doing OO programming? Otherwise I guess I'm looking for a way to specify objects in Spring.NET context XML, but keep them from being resolved until after Caliburn has loaded.
Any ideas?
I'm not familiar with Caliburn but if you want to delay instantiation then you could mark your objects in xml as lazy-init, like this:<object id="foo" type="..." lazy-init="true"/>
This way they will be instantiated when you first request them
I managed to solve this by maintaining a separate list of caliburn-dependent spring context XML files. I loaded these into the ApplicationContext object by adding the following code at the beginning of the overridden DisplayRootView() method in my application's bootstrapper:
var objectDefinitionReader = new XmlObjectDefinitionReader(applicationContext);
objectDefinitionReader.LoadObjectDefinitions(GetCaliburnDependentContextFiles());
applicationContext.Refresh();

Best way to use an IoC container for retrieving runtime settings

I have an C# dll project for which I have to store the runtime settings in an external XML file, and this dll will be used in an ASP.NET/ASP.NET MVC application for which I also have to store the runtime settings in a external file.
Which IoC container can be used to create an object with the runtime settings loaded from a specific external file (or app.config/web.config), and also works for web applications running in medium trust? Any howto/tutorial would be greatly appreciated.
So far I've found only this articles:
Use Castle Windsor to Read Your Config Files Automatically
Getting rid of strings (3): take your app settings to the next level
Update
I'm sending mails from my dll to a variable number of SMTP servers, based on the current record type. For type A I'm using a given SMTP server+port, for type B I'm using an alternate set of server+port values. Of course, I want to be able to modify those values after deployment, so I store them in a XML file.
If I'm storing the SMTP settings as a SMTPConfiguration class with 2 properties (SMTPServer as String and SMTPPort as Int32), is it possible to return from an IoC container the required object based on the given record type, and what is the best way to read the runtime settings in order to build the returning object?
Update2
Let's say I'm storing in the configuration file the following parameters: ASMTPServer, BSMTPServer, ASMTPPort, BSMTPPort.
I can use Castle DictionaryAdapter to read all those settings as properties of an AppConfiguration class.
What is the recommended method to specify that the required SMTPConfiguration class should use ASMTPServer and ASMTPPort values if I'm using a type A record as a parameter (and should use BSMTPServer and BSMTPPort values if I'm using a type B record as a parameter) ? Also, how can I specify that the AppConfiguration is required in this process?
Is there a pattern for initializing objects created wth a DI container
Windsor Config Parameters With Non-Primitive Types

Resources