How can I store sensitive data in Java configuration files? - java

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.

Related

Multiple Data sources for C3P0

I am developing a tool that receives different connection parameters to test values in different databases (a plugin for Nagios in jNRPE that keeps an open connection to different databases).
Because the configuration is dynamic (there could be more databases or they can be removed) I cannot have a configuration file.
I want to know if I should have an instance of C3P0 per database or can I use the same instance and just change the URL each time I ask for a connection?
The code is at github:
https://github.com/angoca/db2-jnrpe/blob/master/src/main/java/com/github/angoca/db2_jnrpe/database/pools/c3p0/DBCP_c3p0.java
If not, how can I get multiple pool for multiple databases dynamically?
You'll need a different c3p0 DataSource for each JDBC url. A Connection pool must contain homogeneous Connections: all checked out Connections must be equivalent from a client's perspective. If Connections from multiple databases were included in the same pool, clients would have no way of specifying or knowing which db they were communicating with.
(If you are replicating, say, a read-only DB and you really want Connections from multiple sources to live in a single pool, because they are guaranteed to be equivalent from a client's point of view, you could do that by defining a custom, unpooled DataSource that round-robined or randomly chose a replicant, and then pooling the DataSource via c3p0's DataSources factory.)
It is very easy to dynamically create and configure c3p0 DataSources. See example code here.
If you capture your dynamic config as a map of c3p0 property names to values, there's also an alternative, more concise way to get a DataSource with that configuration.

How do I specify a server to get an EJB from?

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.

moving from single webapp to multiple webapps connecting to same database

I have a JAVA webapp which is using DB connection pooling for Tomcat+MySQL config.
I have another JAVA webapp which i want to deploy in the same Tomcat and connect to same MySQL database (even access the data from same tables).
I havent figured out a way how to achieve the same.
Should I have connection pooling context.xml for each of the webapps?
Or should I have a global configuration.
In the first case , I assume there is nothing different that i need to do. Only to deploy the webapp which has its own context.xml.. Please correct me if i'm wrong.
If having a global config is a better solution, how to achieve that. Haven't found any good tutorials about it. What changes in each of webapps need to made , so that it knows that it needs to read the global config.
There's nothing wrong with having a separate context for each webapp unless you want to centrally manage changes to the database (i.e. migrate it to a different DB, change connection parameters). If you think your connection properties will change or you want that flexibility then you can use a JNDI datasource in tomcat and manage it there (google is your friend for that).

Java - DBCP vs JNDI?

I am a newbie and I have created a few simlpe Java Swing applications. I was able to use apache commons DBCP to create a connection pool and access the datasource.
I have recently started to create java web based applciations using JSP and Servlets. I have learnt to use JNDI to access the datasource. I update the XML files and use InitialContext() and lookup("java:comp/env") and that is it!!!! I am using Apache Tomcat as my Servlet/JSP container.
1. But where is the DB connection pool created?
2. If yes, then does that mean JNDI somehow uses the DBCP internally?
When I have to create a DBCP for Swing applications, I had to first create an instance of GenericObjectPool and then create a connection factory object and finally a PoolableConnectionFactory object to create the Datasource which will be used to get a connection.
JNDI is a mechanism to pass objects from one part of the system to another (in technical terms across class loaders). This is most useful for classes and interfaces found in the Java Runtime like String or DataSource.
This means that in your case JNDI is just a transport mechanism and you need to have the actual connection pool defined elsewhere. Most web containers have a mechanism for defining a system wide connection pool, and JNDI then allows you to get to it.
Tomcat use a custom implementation of Apache DBCP and Apache Pool for the JNDI Datasource. These libraries are located in a single JAR at $CATALINA_HOME/lib/tomcat-dbcp.jar.
The main package is org.apache.tomcat.dbcp for avoid conflicts with the regular packages form Apache Commons.
JNDI is a mechanism of locating remote resources via lookup. It has nothing in common with connection pooling libraries. These libraries, of which c3p0, DBCP and BoneCP, are the most famous, allow you to create data sources with ability to pool connections and/or statements. If this data source is used within your application, you don't need to use JNDI, if it is located on a remote system (for instance, in Tomcat), you need to use JNDI to get access to the data source.
As a side note, why did you choose to work with old-school Servlet/JSP combo? It is a better idea to work with JSP successor, facelets that is a preferred view technology in JSF 2.x.
Another comment is to transfer management of your data source to a well-known framework. One direction might be to use an ORM, for example, Hibernate, to manage your data source (which was created with connection pooling in mind).

Is there any performance difference between these two JDBC Connectivity?

I have used MySqlDataSource for in jdbc connectivity.I have used following code
MysqlDataSource d = new MysqlDataSource();
d.setUser("user");
d.setPassword("pass");
d.setServerName("hostname.com");
d.setDatabaseName("db");
Connection c = d.getConnection();
Also i have searched there is an option of Configuring a MySQL Datasource in Apache Tomcat.
Is there any performance difference between these two? which one is best to use?
Configuring Datasource in tomcat will help you to share same data source between applications running in same tomcat. that Datasource will be managed by container (tomcat in your case).
while the Datasource created in code will be created by your application and can be used by that application only.
So if you have multiple application running on tomcat and accessing same data source, that configuring Datasource in tomcat will be good approach and have performance factor because only one data source is created and not having separate connections for each application
But if you have only single application that the first approach you have used is good one
They both use the internally the same driver, i dont think the performance is much different here, i guess if you need to access teh database only at that place and the enduser isn't supposed to use his own authentication you may use it directly from java, but if you will need the connectivity on different places it could be helpful to configure this using apache configuration, specially that if anything changes like database server, user name or whatever you don't need to get in the code to change it, this could be very important if end users have to set their own configurations.
The improvement of configuring a pool of Connections (as the one provided by tomcat) is mainly that you will actually create and close a lot less of connections.
When using a pool, when you request a Connection to a pool it will look if it has any connection already created and available for reuse and, if it has, it will provide you with it (instead of creating a new Connection, which is a heavy operation). You must still close() a Connection provided by Tomcat so Tomcat knows that it can now reuse when it is requested again.
Additionally, the advantage of the pool is that your code does not need to know the configuration data for the Connection. He just requests a Connection from a given pool and the sysadmin configures it, allowing for greater flexibility (the sysadmin does not need to know how to configure your app, just how to configure the Tomcat which is fairly more standard).

Categories

Resources