I used Tomcat's JDBC connection pool previously where it could be easily configured in Java.
Now I use Jetty 8.
How can I use JDBC connection pooling in Jetty? I looked here however I don't know where to put those XML snippets.
You can configure all JNDI resources in a jetty.xml file or in a WEB-INF/jetty-env.xml file, or a context XML file. For more information, see JNDI.
You will also need to add the pool implementation jar file to the classpath.
Related
We had recently moved to building projects using Maven. Earlier, all the JARs were added in libs folder and added to classpath. While moving to the Maven build, I missed to add a dependency to the 'sqlite-jdbc'. This library is required to read data from a local .db3 file.
As the 'org.sqlite.JBDC' class was loaded by calling the code Class.forName("org.sqlite.JDBC"), there was no compilation error and I deployed the WAR file and servlet failed in the server. I was thinking of a way to find the issue at the compilation time itself to avoid any such mistakes in the future. Can I simply call the JDBC.PREFIX to load the JDBC, so that, If I forget to add the dependency to the pom.xml file, I can find the issue at the compile time, itself?
Is there was difference between Class.forName("org.sqlite.JDBC") vs JDBC.PREFIX to load JDBC class?
No need for Class.forName
There is no generally no need to call Class.forName.
Such calls were used in the early years. Modern Java was changed so that JDBC drivers are automatically loaded and registered with the JVM via the Java Service Provider Interface (SPI) facility.
If you are using books or tutorials advising Class.forName, you may want to obtain more up-to-date learning materials.
DataSource
Furthermore, in Servlet work you generally should not be explicitly accessing the JDBC driver.
Setting the database server address, username, and password would require hard-coding text. When the deployment sysadmins change the IP address, or rotate passwords, your code breaks. You would then have to modify your source code, re-compile, and re-deploy.
Instead, you should externalize such configuration details.
For SQLite, see Using DataSource to connect to SQLite with (Xerial) sqlite-jdbc driver.
JNDI
You can externalize database configuration by using the the DataSource interface. After obtaining a DataSource object at runtime, make database connections by calling its getConnection method. That DataSource object holds the database server address, username, password, and all other settings needed to make a connection to the database.
Obtain a DataSource object at runtime by using JNDI. Your Servlet container may act as the naming/directory server to provide the DataSource object, if your sysadmin so configures it. Or the DataSource can be obtained via JNDI from an external server such as an LDAP server.
Again, the beauty of using DataSource and JNDI is that you as the Servlet programmer need not be involved, or even informed, when the deployment details change.
JDBC driver location
For Servlet work, you generally do not bundle the JDBC driver with your app.
Instead, the JDBC driver goes into a folder managed by your Servlet container. Study the documentation for your particular Servlet container. For Apache Tomcat, see this Answer.
In development, your IDE may need access to the JDBC driver to compile. If so, in your Maven POM, mark the dependency with a <scope>provided</scope> element. This tag tells Maven to omit that dependency from the final build because the dependency will already be present (provided) at runtime.
If you insist on bundling your JDBC driver within the WAR file of your web app, then see the important Comment by Mark Rotteveel.
This topic has been addressed many times on Stack Overflow. Search to learn more.
I have been searching high and low and gathered bits and pieces, apologies if this has already been answered elsewhere but I am unable to find it.
I am writing a web application in Java with Tomcat, and SQL Azure in the backend.
There are multiple servlets accessing the SQL Azure DB. I would like to use Connection Pools as managed by Tomcat 8.5
My application context.xml in META-INF is as follows:
<Context>
<Resource name="jdbc/sqlazure"
auth="Container"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
type="javax.sql.DataSource"
maxIdle="30"
username="[username]"
password="[password]"
url="jdbc:sqlserver://[database]:1433;database=BackInfo;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30"
removeAbandonedTimeout="30"
logAbandoned="true" />
</Context>
In the Java Code, I access the typical way:
InitialContext ic = new InitialContext();ds = (DataSource)ic.lookup("java:comp/env/jdbc/sqlazure");
try(Connection con = ds.getConnection())....
Everything seems to work, so let me confirm my understanding here:
I do not need to specify a separate web.xml since I'm using Tomcat 8.5. Correct ?
Azure will automatically create a pool when I connect in this manner. The number of connections in the pool etc cannot (do not need to?) be configured.
Before I realized I would have other servlets that need to access the database, I had one servlet directly creating a Datasource via SQLServerConnectionPoolDataSource and getting a connection from there. The documentation states:
SQLServerConnectionPoolDataSource is typically used in Java Application Server environments that support built-in connection pooling and require a ConnectionPoolDataSource to provide physical connections, such as Java Platform, Enterprise Edition (Java EE) application servers that provide JDBC 3.0 API spec connection pooling.
Does this mean that when I use SQLServerConnectionPoolDataSource directly to ask for a connection, it will check if Tomcat supports pooling and then is basically using JDBC mechanisms to create a pool of SQL Azure connections managed by Tomcat ?
When getting the DataSource via Tomcat JNDI lookup, using SQLServerDriver as specified in context.xml. When the web app starts up, it will check context.xml and use SQLServerDriver to connect to SQL Azure, check if pooling is supported, if yes then Tomcat is using the driver to automatically creating a connection pool DataSource that it returns ?
I also just thought of one other question. Would it make sense to have a Singleton DataSource class that returns a reference to the pooled connection DataSource, or would it be better to have each servlet lookup the datasource in its init() and store in a private variable ?
Thanks
Based on my understanding, the jdbc connection pool for SQL Server is created by Java Application, not Azure does. My suggestion is that you need to refer to the Tomcat offical documents below to understand the JNDI Resources & JDBC DataSource.
JNDI Resources: http://tomcat.apache.org/tomcat-8.5-doc/jndi-resources-howto.html
JDBC DataSource: http://tomcat.apache.org/tomcat-8.5-doc/jndi-datasource-examples-howto.html
In Tomcat, I have a shared c3p0 jar placed in Tomcat's lib folder with three different applications using it.
Is there a way to identify which application created which connection pool?
An easy thing to do is to use c3p0's named configurations to define a distinct configuration for each application, and let each application construct its own pool. The dataSourceName parameter will let you permanently discriminate between your DataSources, e.g. in a JMX MBean client.
I am about to make a connection to my database and I am using EJB and JPA. I have recently started doing these technologies so I have some problems understand it all at this point:)
I know that the persistence.xml is needed in order to use JPA. It is the file where I configure how to connect to the database, that I know. However it seems like there are multiple ways of doing it.
What would be the difference (or when should I even use the one alternative over the other?) of defining properties such as username, database, password etc. in the persistence.xml file and in Glassfish? Advantages/disadvantages if any.
Underneath on the image I posted I have JDBC Resources and JDBC Connection Pools. I am a litte confused about the terminology of the two. Why don't we add properties such as username, database, password and so on in the JDBC Resources? Could someone explain the difference between them and what they mean?
JDBC Resources
A JDBC resource (data source) provides applications with a means of
connecting to a database. Typically, the administrator creates a JDBC
resource for each database accessed by the applications deployed in a
domain. (However, more than one JDBC resource can be created for a
database.)
http://download.oracle.com/docs/cd/E19316-01/820-4335/ablih/index.html
I think it strange that we add such properties on the pool but not in the resource, but I probably misunderstand the concepts.
In the "JDBC connection pools" you can create container managed JDBC data sources (with connection pooling capabilities). The data source needs to know about at least the JDBC driver, the JDBC URL, username and password.
In the "JDBC resources" you can bind those container managed JDBC data sources to one or more JNDI names so that they are by JNDI available to the deployed web application.
In the persistence.xml you can specify whether to use a local data source or to use a container managed data source. If you want to use a container managed data source, then you should specify its JNDI name. Using a container managed data source has the advantage that you can share a single data source among multiple web applications. In case of JPA, it has also the advantage that you can make use of JTA (container managed transactions) so that you don't need to call transaction.begin(), commit(), rollback() etc in every method.
Would it be possible to programmaticly create a data source in jboss and still have a valid jndi entry for the entity manager to use?
Creating the data source is where I am lost, I hope I can use a MBean that runs on stat-up to handle this.
This would not be my preferred method, but the application I am working on has a global configuration file hosted on another server I am suppose to use for configuration.
update: In this instance I need to create a data source programticly or change the jdbc url of an exsiting datasource. I don't know the DB server url until runtime.
Rather than poking around in the guts of JBoss in order to do this, I suggest using a 3rd-party connection pool utility, such as Apache Commons DBCP. There are instructions on how to programmatically register a DBCP datasource on JNDI here.
The first two lines of the sample code should be unnecessary, just create the default InitialContext and then rebind the datasource reference into it as described.
Here's a post that describes how to create a jboss service archive (SAR) that you can put in your EAR that will deploy a data source when the EAR is deployed, and remove it when the EAR in undeployed.