What I am trying to do is to retrieve a DataSource from a locally running JBoss (EAP 5.1) per JNDI.
It works fine inside a deployed DAO, but I seem to misunderstand something as when I am trying to get the DataSource in a test case, I keep getting a javax.naming.NoInitialContextException when trying
Properties env = new Properties();
env.put(Context.PROVIDER_URL, "jnp://localhost:1099");
final InitialContext ic = new InitialContext(env);
ds = (DataSource) ic.lookup(DATASOURCE_NAME);
If i add
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
I get a ClassNotFoundException for the org.jnp.interfaces.NamingContextFactory
Being new to JNDI and JBoss, I'm stuck at that point. Searching the web just adds to my confusion as all I find are scattered pieces of info that I try to apply by trial-and-error with no real progress.
Thank you
What functionality is it that you are testing? Is it the retrieval of a DataSource or some actual database code? If the latter, then I would suggest not using JNDI at all and using a local DataSource implementation.
This thread shows how to use Commons DBCP to set up local DataSources.
http://forum.springsource.org/showthread.php?16670-Problem-running-JUNIT-test-with-JNDI-datasource
If you really need the JNDI aspect, this example shows how to populate an InitialContext with a minimum of values to get a DataSource back. You can probably use the same Commons DBCP config as above to configure the DataSource(s) that you need.
http://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit
Related
I'm trying to set up a JNDI database connection for my WAR file which will be deployed on WebLogic 12c. This is what I have:
#Bean
public DataSource dataSource() throws DataSourceLookupFailureException {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource("jndiName");
}
In the application.properties file:
spring.datasource.jndi-name=jndiName
This is pieced together from two different sections of the Spring Boot guide:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html#howto-configure-a-datasource
I am confused, why is jndiName stated twice? Am I following correctly - is this the correct way to set up?
I am of the impression that Spring Boot will either automatically retrieve the JNDI name from application.properties, so that I do not need to hardcode the JNDI name into getDataSource(), or if I hardcode the JNDI name in then I wouldn't need to include that property in application.properties in the first place.
From my interpretation, the two sections of the guide covering how to set up a JNDI connection appear to contradict each other. What am I getting wrong? What exactly is the correct way to set this up?
Remove your custom bean and use application.properties but in local environment if you want to run embedded container this approach won't work
To use H2 or any other database in embedded container define profile in main method and then configure your data source. This way it works both in local and production
How to bind a JDBC datasource to JNDI context java:comp/env/jdbc only using code-based approach.
We need to write resource-ref in the web.xml for binding a dataSource to JNDI local context java:comp/env/jdbc.
But I want to use only org.springframework.web.context.AbstractContextLoaderInitializer instead of web.xml(the old approach).
We know the method InitialContext#createSubcontext. But some application servers(e.g. Websphere) do not accept to edit the context java:comp/env/jdbc/.
Any solutions?
Versions:
Spring 4.0.7
Servlet 3.0
You could try a full programmatic approach using Spring's SimpleNamingContextBuilder:
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
DataSource ds = new DriverManagerDataSource(...);
builder.bind("java:comp/env/jdbc/myds", ds); // you control the datasource
builder.activate();
It's mainly there for test-purposes. If you choose to use it then you need to provide your own connection pool (e.g. Apache's Jakarta Commons DBCP).
I once used for testing when I deployed to cloudbees. see this blogpost
This works in "plain" Tomcat. I don't have a EE server to test with, but you could try it and see what happens (I guess the JNDI binding name has to be unique to the server though).
What is your application server?
See if this helps.
How to use JNDI DataSource provided by Tomcat in Spring?
How I can create web application project which is loading the jndi datasource set in the server configuration? I want to make the web application independent from the server and the database. Is it possible.
You create the DataSource in your web/application server and expose it through JNDI
You configure the following hibernate property:
<property name="hibernate.connection.datasource">java:comp/env/jdbc/MyDataSource</p>
This way the application is decoupled from the JNDI provider. Even the JNDI url can be configured using a Maven property, so switching to an application server (that uses a different JNDI resource pattern) is just a mater of adding a new Maven profile.
One better approach is to set up the DataSource in your application configuration.
#Autowired
private DataSource dataSource;
...
properties.put("hibernate.connection.datasource", dataSource);
This way you can use any connection pooling framework, like the fastest connection pooling framework, HikariCP.
You can even set up DataSource proxies, like:
datasource-proxy, to log SQL queries with PreparedStatement parameters
FlexyPool, to monitor connection pooling usage and adjust the pool size using adapting startegies
My WAR application is deployed to Amazon Elastic Beanstalk. They don't support JNDI, but I need it for JPA and unit tests. What JNDI context factory I can use as a workaround? I need a simple open source solution, that would allow me to configure entire factory through jndi.properties. I tried GuiceyFruit, but looks like it doesn't allow data source configuration inside one file. Any suggestions?
ps. OpenEJB will work, but it's an overkill for such a simple task
Try Simple-JNDI. It gives you an in-memory implementation of a JNDI Service and allows you to populate the JNDI environment with objects defined in property files. There is also support for loading datasources or connection pools configured in a file.
To get a connection pool you have to create a file like this:
type=javax.sql.DataSource
driver=com.sybase.jdbc3.jdbc.SybDriver
pool=myDataSource
url=jdbc:sybase:Tds:servername:5000
user=user
password=password
In your application you can access the pool via
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("path/to/your/connectionPool");
You can find more about it at https://github.com/h-thurow/Simple-JNDI.
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