How JBOSS uses db2-ds.xml file to create datasource object for DB2?
If it is about how to create a DataSource you copy $JBOSS_HOME\docs\examples\jca\db2-ds.xml to $JBOSS_HOME\server\default\deploy and customize the settings to fit your JDBC connection-url,user-name etc.
EDIT:
Jboss reads this file, and periodically checks for updates (if configured) and sets up a DataSource which is registered in JNDI and provides a pool of connections depending on underlying driver-class. To see how this is done in detail you should throw a glance into the sourcecode. Search for "-ds.xml" a good startingpoint is: $JBOSS_SRC\console\src\main\org\jboss\console\manager\DeploymentFileRepository.java which looks for "-ds.xml" files.
Related
I am learning Java EE. My instructor told me to implement JNDI DataSource in my learning project. I have found some articles on the subject but I can't see clearly the steps to doing this.
My training project is a Spring MVC application. On the front end it has some Thymeleaf templates, and the data are taken from a PostgreSQL database.
What should be done to implement JNDI here? I don't even know why I need it. I was only told that this configuration should be considered obsolete and low-level, but I have no idea why.
Now the database is configured as follows:
a props file with the following content:
driver=org.postgresql.Driver
url=jdbc:postgresql://localhost/trainingproject
dbuser=postgres
dbpassword=Password
a .sql file which looks like this:
DROP TABLE IF EXISTS table1;
CREATE TABLE table1
(
row1 SERIAL PRIMARY KEY,
row2 CHARACTER VARYING(64)
);
a DataSource bean:
#Bean
public DataSource datasource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getProperty(DRIVER));
dataSource.setUrl(environment.getProperty(URL));
dataSource.setUsername(environment.getProperty(USER));
dataSource.setPassword(environment.getProperty(PASSWORD));
}
PGSimpleDataSource implementation of DataSource is bundled with JDBC driver.
The JDBC driver for Postgres at https://jdbc.postgresql.org includes an implementation of DataSource: PGSimpleDataSource
PGSimpleDataSource ds = new PGSimpleDataSource() ;
ds.setServerName( "localhost" );
ds.setDatabaseName( "your_db_name_here" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
For more info:
The Javadoc for DataSource.
The Javadoc PGSimpleDataSource.
My Answer to the Question, Produce a DataSource object for Postgres JDBC, programmatically
The JDBC driver’s manual.
JNDI
Your question conflates two issues: DataSource and JNDI.
A DataSource is a simple object holding all the connection info needed to make a connection to a database. This includes a username, a password, the address of the database server, and any number of standard and proprietary feature settings. By proprietary, I mean Postgres-specific feature settings versus Microsoft SQL Server-specific versus Oracle-specific, etc. Look at the Javadoc for DataSource to see how simple it is, basically just a getConnection method. You can obtain a DataSource object with or without JNDI; the two are orthogonal issues.
JNDI is much more complex. JNDI is an interface for obtaining from a naming/directory server the configuration info needed by your app at runtime. Using this interface to such a server means you need not include deployment details in your codebase; you look up needed details on-the-fly at runtime.
Database connection info is but one of many kinds of info you might want to obtain from a JNDI server. You might also look up web services servers, logging services, and so on.
So rather than hard-coding your database connection info, you might want to “discover” the proper database connection info when launching your app. Your testing machines will use a bogus database server while your production deployment machines will use a different database server. These database servers may not be known to the programmer at compile time, or may not even exist yet. A look-up needs to be done, and JNDI is a standard way to do so without vendor lock-in.
How you configure database connection info to be delivered by a JNDI-compliant naming/directory server as a DataSource object to your app differs wildly depending on the particular server environment of your enterprise. Given your last code example, it looks like you are not actually accessing a JNDI server in your class, so JNDI is moot.
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.
In a java application, If we want to use javax.sql.DataSource instead of java.sql.DriverManager to get connections, which approach would be better to create DataSource and WHY?
Create DataSource in the application itself at the application startup time
or
Configure DataSource in the application server and get it via JNDI
Well, it actually depends upon the requirement. You can take this as a general rule.If you have multiple applications and sharing the same DataSource, then it can be a good choice to configure the DataSource in the server. Otherwise, if this is the only application uses the DataSource, then you can have it in the application level itself.
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).
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).