-
1. Re: How to encrypt Database password in modeshapeConf.xml
rhauch May 28, 2014 11:59 AM (in response to deepak_a)The only way is if you have JNDI available and can register a DataSource in JNDI. Then you can use the "mode:dataSourceJndiName" property to specify the JNDI name of the data source rather than specifying the connection details.
-
2. Re: How to encrypt Database password in modeshapeConf.xml
deepak_a May 28, 2014 1:11 PM (in response to rhauch)Is it possible to access a JNDI set up in a remote JVM?
I have a JBoss app server in a different JVM that has the JNDI datasource set up for the same database as Modeshale needs to connect to - is it possible to refer a JNDI in remote JVM?
-
3. Re: How to encrypt Database password in modeshapeConf.xml
rhauch May 28, 2014 1:12 PM (in response to deepak_a)No, it's not.
-
4. Re: How to encrypt Database password in modeshapeConf.xml
deepak_a Jun 3, 2014 10:14 AM (in response to rhauch)Hi.
I have set up a local JNDI (in my J2SE app). And I have updated modeshape-conf.xml to refer the JNDI.
I can confirm the JNDI can be accessed by a test class (so JNDI is definitely set up).
But modeshape still says: javax.naming.NameNotFoundException: jdbc not bound
As per the below link:
https://docs.jboss.org/author/display/MODE/Using+ModeShape#UsingModeShape-RepositoryFactoryandJNDI
One of the more popular ways to find a Repository instance is to use JNDI, though this only works in environments like web servers or application servers that contain a JNDI implementation. It also assumes that a Repository instance has already been registered in JNDI; how this is done is specific to the environment.
Does this mean - I can't use modeshape in a J2SE environment (without web server or app server)? Pls clarify.
I would be reluctant to use an app server just for this.
regards,
Deepak.
-
5. Re: How to encrypt Database password in modeshapeConf.xml
rhauch Jun 3, 2014 10:44 AM (in response to deepak_a)1 of 1 people found this helpfulAs per the below link:
https://docs.jboss.org/author/display/MODE/Using+ModeShape#UsingModeShape-RepositoryFactoryandJNDI
One of the more popular ways to find a Repository instance is to use JNDI, though this only works in environments like web servers or application servers that contain a JNDI implementation. It also assumes that a Repository instance has already been registered in JNDI; how this is done is specific to the environment.
Does this mean - I can't use modeshape in a J2SE environment (without web server or app server)? Pls clarify.
You absolutely CAN use ModeShape within a JavaSE environment, and many people do. While standard JavaSE doesn't provide JNDI out of the box, some JavaSE environments and/or third-party libraries do provide JNDI behavior. That means that with 2.x you would be able to specify a DataSource via JNDI only if your environment has JNDI. ModeShape 3.x can do a few more things with JNDI (like automatically registering the repository in JNDI as described in the documentation), but obviously it only does this if JNDI if it is available within the environment.
Now, you did say earlier that you're using ModeShape 2.70, but the link you provided is actually for the 3.x codebase. So while the information in that link is still incorrect, be sure that you're looking at the right documentation set for the version you're using.
The 2.7.x documentation is available here: https://docs.jboss.org/author/display/MODE27/Home
The 2.8.x documentation is available here: https://docs.jboss.org/author/display/MODE28/Home
The 3.x documentation for all 3.x releases (3.0-3.8.0) is available here: https://docs.jboss.org/author/display/MODE/Home
The documentation for the 4.x releases (4.0.0.Alpha3) is available here: https://docs.jboss.org/author/display/MODE40/Home
-
6. Re: How to encrypt Database password in modeshapeConf.xml
deepak_a Jun 3, 2014 12:15 PM (in response to rhauch)Hi,
Thanks for clarifying that.
I am still getting a NameNoFoundException. I think its likely because I am not passing in the JNDI context properties correctly to the Properties. Is there any example you can point to? especially on how context properties are passed in/set prior to loading the modeshapeConfig.xml
[2014-06-03 17:02:22,826 modeshape-start-repo-2-thread-1] NamingHelper INFO JNDI InitialContext properties:{}
[2014-06-03 17:02:22,830 modeshape-start-repo-2-thread-1] DatasourceConnectionProvider ERROR Could not find datasource: jdbc/reformDS
javax.naming.NameNotFoundException: jdbc not bound
This is what i do
Properties props = new Properties();
props.put("modeShapeConfigURL", "classpath:modeShapeConf.xml");
//Do I need the below 2 properties to be set?
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
props.put(Context.PROVIDER_URL, "jnp://" + "localhost" + ":1099");
and in my modeshapeConf.xml I have the following
<mode:source jcr:name="store" mode:autoGenerateSchema="disable" mode:classname="org.modeshape.connector.store.jpa.JpaSource" mode:compressData="false" mode:creatingWorkspacesAllowed="true" mode:dataSourceJndiName="jdbc/reformDS" mode:defaultWorkspaceName="default" mode:dialect="org.hibernate.dialect.Oracle10gDialect" mode:largeValueSizeInBytes="10000" mode:model="Simple" mode:predefinedWorkspaceNames="default,system" mode:referentialIntegrityEnforced="true" mode:retryLimit="3" mode:showSql="false"/>
I have also tried with
<mode:source jcr:name="store" mode:autoGenerateSchema="disable" mode:classname="org.modeshape.connector.store.jpa.JpaSource" mode:compressData="false" mode:creatingWorkspacesAllowed="true" mode:dataSourceJndiName="java:jdbc/reformDS" mode:defaultWorkspaceName="default" mode:dialect="org.hibernate.dialect.Oracle10gDialect" mode:largeValueSizeInBytes="10000" mode:model="Simple" mode:predefinedWorkspaceNames="default,system" mode:referentialIntegrityEnforced="true" mode:retryLimit="3" mode:showSql="false"/>
I do the following to test if the JNDI context is available and it works perfect -
final Hashtable<String, String> _properties = new Hashtable<String, String> ();
_properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
_properties.put(Context.PROVIDER_URL, "jnp://" + "localhost" + ":1099");
try {
final Context _context = new InitialContext(_properties);
Object obj = _context.lookup("jdbc/reformDS");
if (null != obj) {
System.out.println("OBJ: " + obj.getClass());
org.apache.commons.dbcp.BasicDataSource ds = (org.apache.commons.dbcp.BasicDataSource)obj;
JdbcTemplate jdbcTemplate2 = new JdbcTemplate(ds);
String sql = String.format("update MESSAGE_LOG set PROCESS_INSTANCE_ID = 123456 where ID =42395 ");
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
-
7. Re: How to encrypt Database password in modeshapeConf.xml
rhauch Jun 3, 2014 1:04 PM (in response to deepak_a)What's the library that is providing JNDI in your JavaSE app? You can see the code for the JNDI lookup in 2.7.0.Final here: https://github.com/ModeShape/modeshape/blob/modeshape-2.7.0.Final/extensions/modeshape-connector-store-jpa/src/main/java/org/modeshape/connector/store/jpa/JpaSource.java#L1313
Perhaps try code exactly like that? Notice that we're not passing any properties to the InitialContext - is there any way to do that with the JNDI library you're using?
Worse comes to worse, you could subclass the JpaSource class and override that method.
-
8. Re: How to encrypt Database password in modeshapeConf.xml
deepak_a Jun 4, 2014 9:48 AM (in response to rhauch)Hi,
Thanks for pointing to the source code.
The library I use for starting the JNDI server has the following classes (used to start the JNDI server)
import org.jnp.server.Main;
import org.jnp.server.NamingBeanImpl;
//Snippet of the code
System.setProperty("java.rmi.server.hostname", "localhost"); System.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); System.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces"); final NamingBeanImpl namingInfo = new NamingBeanImpl(); namingInfo.start(); final Main jndiServer = new Main(); jndiServer.setNamingInfo(namingInfo); jndiServer.setPort(1099); jndiServer.setBindAddress("localhost"); jndiServer.setRmiPort(1098); jndiServer.setRmiBindAddress("localhost"); jndiServer.start(); final Hashtable<String, String> _properties = new Hashtable<String, String> (); _properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory"); _properties.put(Context.PROVIDER_URL, "jnp://" + "localhost" + ":1099"); final Context _context = new InitialContext(_properties); _context.createSubcontext("jdbc"); JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSource()); System.out.println("jdbcTemplate: " + jdbcTemplate.getClass()); System.out.println("getDataSource(): " + getDataSource().getClass()); _context.bind("/jdbc/reformDS", getDataSource()); //JNDI started
//Test the JNDI Context Tree
final Hashtable<String, String> _properties = new Hashtable<String, String> ();
_properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
_properties.put(Context.PROVIDER_URL, "jnp://" + "localhost" + ":1099");
final Context _context = new InitialContext(_properties);
Object obj = _context.lookup("/jdbc/reformDS");
if (null != obj) {
System.out.println("OBJ: " + obj.getClass());
org.apache.commons.dbcp.BasicDataSource ds = (org.apache.commons.dbcp.BasicDataSource)obj;
JdbcTemplate jdbcTemplate2 = new JdbcTemplate(ds);
String sql = String.format("update MESSAGE_LOG set PROCESS_INSTANCE_ID = 123456 where ID =42395 ");
int update = jdbcTemplate2.update(sql);
System.out.println("Update*****************: " + update);
}
In the test code where I extract the object from JNDI context - I "must" pass the JNDI host/port details - otherwise its not able to find the JNDI context.
I am curious to find how the method getConnection() in class JpaSource knows where/how to get the JNDI context? Is the host/port details passed in via a JNDI.properties file?
regards,
Deepak.
-
9. Re: How to encrypt Database password in modeshapeConf.xml
rhauch Jun 4, 2014 9:59 AM (in response to deepak_a)In the test code where I extract the object from JNDI context - I "must" pass the JNDI host/port details - otherwise its not able to find the JNDI context.
I am curious to find how the method getConnection() in class JpaSource knows where/how to get the JNDI context? Is the host/port details passed in via a JNDI.properties file?
The JpaSource class just create an InitialContext with the default constructor. That normally works in app/web server environments that come with JNDI. If I had to do it over again, I'd use a protected method to obtain the Context so that it's easier to subclass, and maybe even provide a way for properties to be defined and passed into the InitialContext.
But 2.x is no longer a supported/maintained version. You can, however, just create a subclass of JpaSource that overrides the method that does what you need. (I'd suggest copy the existing code for the method and in your overridden method just change how InitialContext is constructed by passing in properties, which you can determine from new fields in your JpaSource subclass that you can then set in the configuration file -- or even hard code if that's good enough for your application.)
-
10. Re: How to encrypt Database password in modeshapeConf.xml
deepak_a Jun 5, 2014 7:36 AM (in response to rhauch)1 of 1 people found this helpfulHi,
Thanks for the pointer. I looked up the source code for InitialContext
191 public More ...InitialContext() throws NamingException {
192 init(null);
193 }
The init method in turn calls
That method seems to loop over all System.properties and picks up only those properties needed for JNDI.
So all I had to do was set the required properties just before modeshapeConf,xml is loaded
i.e.
System.getProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.getProperty(Context.PROVIDER_URL, "jnp://" + "localhost" + ":1099");
Now I am able to load the InitialContext even without passing the environment details via its constructor,
-
11. Re: How to encrypt Database password in modeshapeConf.xml
rhauch Jun 5, 2014 9:25 AM (in response to deepak_a)[The InitialContext()] method seems to loop over all System.properties and picks up only those properties needed for JNDI.
So all I had to do was set the required properties just before modeshapeConf,xml is loaded
i.e.
System.getProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.getProperty(Context.PROVIDER_URL, "jnp://" + "localhost" + ":1099");
Now I am able to load the InitialContext even without passing the environment details via its constructor,
Great tip. Thanks!