So, I read several times that if you use a Java EE container, you do not need to add environment params to an InitialContext in order to be able to use JNDI.
So I tried this:
#Bean
public DataSource dataSource() {
JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
return jndiDataSourceLookup.getDataSource("java:global/ExpensesDataSource");
}
However, retrieving a datasource using JNDI like this gives me a NoInitialContextException, telling me to specify the environment params.
Now, okay, so seems I was wrong to think it would work so flawlessly, so I tried retrieving the datasource like this:
#Bean
public DataSource dataSource() {
Properties jndiProperties = new Properties();
jndiProperties.setProperty(Context.PROVIDER_URL, "jnp://localhost:1099");
jndiProperties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
jndiProperties.put("java.naming.factory.url.pkgs", "org.jboss.naming.org.jnp.interfaces");
JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
jndiDataSourceLookup.setJndiEnvironment(jndiProperties);
return jndiDataSourceLookup.getDataSource("java:global/ExpensesDataSource");
}
However this gives me a javax.naming.CommunicationException: Failed to connect to server localhost:1099
I've also tried just using localhost:1099 or localhost, none of them worked.
So my question is: do I even need to specify these properties, since JBoss 8 is a Java EE container to my knowledge. And if so, what provider url do I need to specify here?
If you use javax.naming.InitialContext, you don't need to specify environment params, just like you said. For example:
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:jboss/datasources/ExampleDS");
Not sure how JndiDataSourceLookup works..
For looking up a datasource, you can inject it using #Resource (inside an ejb context)
#Resource(name= "java:jboss/datasources/ExampleDS")
private Datasource ds;
Hope it helps!
Related
I have a simple dataSource() method to set datasource in Spring MVC using JDBC for PostgreSQL. I read database configuration from the resources.database.properties file. But it cannot read database username.
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(Objects.requireNonNull(environment.getProperty("driver")));
dataSource.setUrl(environment.getProperty("url"));
dataSource.setUsername(environment.getProperty("username")); // - returns host username
dataSource.setPassword(environment.getProperty("password"));
return dataSource;
}
The resources.database.properties contains this:
driver=org.postgresql.Driver
url=jdbc:postgresql://172.17.0.2:5432/first_db
username=postgres
password=mypassword
If I hardcode the user name it works fine.
I just need to get my PostgreSQL user name (witch is running on my Docker container). What is wrong with this?
So there is a collision with another environment variable, "username". So you either rename the "username" in the properties or, even better, you can use a namespace:
database.driver=org.postgresql.Driver
database.url=jdbc:postgresql://172.17.0.2:5432/first_db
database.username=postgres
database.password=mypassword
Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(Objects.requireNonNull(environment.getProperty("database.driver")));
dataSource.setUrl(environment.getProperty("database.url"));
dataSource.setUsername(environment.getProperty("database.username"));
dataSource.setPassword(environment.getProperty("database.password"));
return dataSource;
Trying to connect my spring/hibernate project which is running locally on my machine to my aws rds.I am trying to modify my previous setup which was a h2 local database datasource. Unsure how to combine the xml and java config to import the bean into the java config?
My dataconfig.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aws-context="http://www.springframework.org/schema/cloud/aws/context"
xmlns:jdbc="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cloud/aws/context
http://www.springframework.org/schema/cloud/aws/context/spring-cloud-aws-context.xsd">
<aws-context:context-region region="eu-west-1a"/>
<aws-context:context-credentials>
<aws-context:simple-credentials access-key="
my key" secret-key="my key" />
</aws-context:context-credentials>
<jdbc:data-source
db-instance-identifier="mydb"
password="my password">
</jdbc:data-source>
Dataconfig.java
#Configuration
#PropertySource("app.properties")
#EnableJpaRepositories(basePackages = "haughton.icecreamapi.dao")
public class DataConfig {
#Autowired
private Environment env;
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
factory.setDataSource(dataSource());
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan(env.getProperty("entity.package"));
factory.setJpaProperties(getHibernateProperties());
return factory;
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
properties.put("hibernate.implicit_naming_strategy",env.getProperty("hibernate.implicit_naming_strategy"));
properties.put("hibernate.format_sql", env.getProperty("hibernate.format_sql"));
properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
//removed to keep db consistent
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
return properties;
}
#Bean
public DataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
// Driver class name
ds.setDriverClassName(env.getProperty("db.driver"));
// Set URL
ds.setUrl(env.getProperty("db.url"));
// Set username & password
ds.setUsername(env.getProperty("db.username"));
ds.setPassword(env.getProperty("db.password"));
return ds;
}
}
SPRING CLOUD / AWS
The Spring Cloud doc Section 3.1.2 tells you how to move your XML config into annotations. It says to add some annotations to your Application Configuration object. (Create a new one if you don't have one yet.)
#Configuration
#EnableContextInstanceData
public static class ApplicationConfiguration {
}
You have some options for specifying your keys:
use the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
use the system properties aws.accessKeyId and aws.secretKey
use the user specific profile credentials file. To do this, just run aws configure from whatever user is running your application and set the keys and region there. If you go this route, remember to do this in production as part of your system setup.
use the instance profile credentials (you aren't running on an EC2 instance, so this won't work for you)
I recommend going with the 3rd bullet point option.
You may also be able to wire up the values from your application.properties file, but I don't know how to do that.
DATA SOURCE
Source: https://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-one-configuration/
#Configuration
class PersistenceContext {
#Bean(destroyMethod = "close")
DataSource dataSource(Environment env) {
HikariConfig dataSourceConfig = new HikariConfig();
dataSourceConfig.setDriverClassName(env.getRequiredProperty("db.driver"));
dataSourceConfig.setJdbcUrl(env.getRequiredProperty("db.url"));
dataSourceConfig.setUsername(env.getRequiredProperty("db.username"));
dataSourceConfig.setPassword(env.getRequiredProperty("db.password"));
return new HikariDataSource(dataSourceConfig);
}
//Add the other beans here
}
This example uses the Hikari connection pooling framework. IF you want to use that, you'll have to add the appropriate dependency.
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.7.4</version>
</dependency>
That requires Java 7; there are other compatibility versions available for Java 6-9. Of course, you can use different connection pool if you wish.
1) Difference between the constructors of InitialContext.
public InitialContext(Hashtable<?,?> environment)
what does this constructor do and what will environment parameter do .
2)
Hashtable<Object, String> environment= new Hashtable<Object, String> (2);
--
--
Context ctx = new InitialContext( environment);
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setJdbcUrl(----);
comboPooledDataSource.setDriverClass(----);
ctx.bind (__);
please explain each line what does it do..
3)Why to create combopooldatasource object ,instead we can create datasource object..??
Answer for 3rd question : Datasource can not be created for ordinary domains,its only for JNDI domains.
For 1st : InitialContext is used to set the environment to create the pooled datasource by creating .bindings file
For 2nd : Context sets the environment.
ComboPooledDataSource object is created.
For that object the url and jdbc driver class wll be set to take the connections from DB to the Pool.
Above set things will be binded to the context and it will be wriiten in .bindings file in encoded format
I have created a dynamic web project in WAS 7.0.0.25. I have configured datasource as jdbc/DWLConfig in the WAS. I am trying to lookup this datasource in the servlet from the web project i have created.
if i give java:comp/env/jdbc/DWLConfig, it is giving me NameNotFoundException. But if i give jdbc/DWLConfig, then it is working fine.
Actually, from the servlet, i am calling another project which i dont have access to edit, always looks like java:comp/env/jdbc/DWLConfig. So it is throwing exception for me.
Do i need to add any reference in the web project which i have created.?
The problem might be related to the base JNDI. You will notice why it is not working from the following example:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
// Right
DataSource ds = (DataSource) envCtx.lookup("jdbc/DWLConfig");
// Wrong. because base JNDI already created.
DataSource ds = (DataSource) envCtx.lookup("java:comp/env/jdbc/DWLConfig");
I am trying to use a datasource that I set up on my weblogic server.
datasource JNDI name = thinOracleDataSource
in my code I have the following
public class DAOBean implements java.io.Serializable {
private Connection conn;
public void connect() throws ClassNotFoundException,
SQLException, NamingException {
Context ctx = new InitialContext();
// Lookup using JNDI name.
DataSource ds = (javax.sql.DataSource) ctx.lookup("thinOracleDataSource");
conn = ds.getConnection();
}
But I get this error
javax.naming.NameNotFoundException: While trying to look up /thinOracleDataSource in /app/webapp/PreAssignment2/24911485.; remaining name '/thinOracleDataSource'
am I looking the JNDI name in the right way? or am I missing something? Thanks for any help!!
EDIT:
This is the jndi tree that I can get from the weblogic console
Try naming your datasource jdbc/thisOracleDataSource in Weblogic and reference it as:
DataSource ds = (javax.sql.DataSource) ctx.lookup("jdbc/thinOracleDataSource");
Also, make sure the datasource is "targeted" to your weblogic Java server. All of this can be done in the Weblogic admin console.
Your JNDI key should look like approximately "java:comp/env/jdbc/thinOracleDataSource".
You can verify it by using Weblogic console that allows access (and probably search) in JNDI. So, you can check this manually before writing the code.