How to configure SQLite in Tomcat 6? - java

Can you please provide the steps on how to use sqlite in tomcat 6? I am using Xerial sqlite jdbc driver. In my application, I have got multiple sqlite databases (.db files) and would need to connect to a different sqlite database depending on what user logs in ? Where can I put all the .db files - with in the webapp root's directory or any where on the system or with in WEB-INF?
Thanks,
Deep

I just went through configuring sqlite3 with Tomcat 7. Everything is working now, so thought I'd share my setup.
- Download the JDBC driver (org.sqlite.JDBC) that lives in sqlite-jdbc-3.7.2.jar (or whatever the latest version is). https://bitbucket.org/xerial/sqlite-jdbc/downloads and copy it to yourTomcat/lib
- You can copy the sqlite db anywhere you want to. For my setup, I created a 'dbs' directory under my tomcat install, and put it there.
Now set up your app. If you don't have a META-INF/context.xml file, then create one. This is a minimal file:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/yourdb"
auth="Container"
type="javax.sql.DataSource"
driverClassName="org.sqlite.JDBC"
url="jdbc:sqlite:/${catalina.home}/dbs/yourDB.db"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory">
</Resource>
</Context>
Then add the following to WEB-INF/web.xml:
<resource-ref>
<description>Reviews Database</description>
<res-ref-name>jdbc/yourdb</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
At this point, you should be good to go. Here is some sample code for accessing the database (I have a table 'admin' with a column 'username'):
public String getName() {
LOG.info("getting name : " + this.name);
try {
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/yourdb");
Connection conn = ds.getConnection();
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select username from admin");
this.name = rs.getString(1);
} catch (SQLException se) {
LOG.info(se.toString());
} catch (NamingException ne) {
LOG.info(ne.toString());
}
return this.name;
}
Note: some distros of tomcat don't come with tomcat.dbcp by default, if you run into problems it may be easier to reference the dbcp class that comes with commons, org.apache.commons.dbcp.BasicDataSourceFactory. I had this problem with tomcat.dbcp not included in my tomcat7 installation and once I switched the reference in context.xml everything was working fine.

What we did is pretty similar. Unfortunately you cannot create a SQLite Connection pool on Tomcat as SQLite has a database file for each user.
Just copy the jar file in TOMCAT_HOME/lib folder but you cannot call a connection via JNDI.
You will have to do something like this:
/**
*
* #param driverClassName
* #param url
* #param user
* #param password
* #throws SQLException
* #throws Exception
*/
public DefaultJdbcTransaction(String driverClassName, String url, String user, String password) throws SQLException {
super();
// TODO Auto-generated constructor stub
try {
Class.forName(driverClassName).newInstance();
if (user == null && password == null) {
connection = DriverManager.getConnection(url);
} else {
connection = DriverManager.getConnection(url, user, password);
}
} catch (InstantiationException e) {
// TODO Auto-generated catch block
throw new SQLException(e);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
throw new SQLException(e);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
throw new SQLException(e);
}
}
Where url="jdbc:sqlite:/path/to/sqlite/file/userId.db", driverClassName="org.sqlite.JDBC", and (user = password = null).
I'm using sqlitejdbc-v056.jar.
Hope this helps

Related

Why does this simple JDBC/JOOQ code creates 10 connections to my database?

Im working on a spring project ran on a local environment using SpringToolSuite. I'm using Putty to create a tunel to access an app server from which i can query my MySQL database (i have to use SSH). So i'm running this simple code:
public static void getConnection() {
try {
connection = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DSLContext create = DSL.using(connection, SQLDialect.MYSQL);
Personne personne = Personne.PERSONNE.as("personne");
Evenement evenement = Evenement.EVENEMENT.as("evenement");
Genealogie genealogie = Genealogie.GENEALOGIE.as("genealogie");
Lieu lieu = Lieu.LIEU.as("lieu");
Result<Record3<Integer,Integer,String>> result = create
.select(DSL.countDistinct(personne.ID).as("countRs"),
evenement.IDGROUPE2.as("group2Rs"),
lieu.LIBELLE.as("libelleRs"))
.from(evenement.innerJoin(personne)
.on(personne.ID.eq(evenement.IDPERS))
.innerJoin(genealogie)
.on(genealogie.ID.eq(personne.IDGEN))
.innerJoin(lieu)
.on(lieu.ID.eq(evenement.IDGROUPE2)))
.where(personne._NOM.eq(" ")
.and((personne._PRENOM.eq(" ")
.or(personne._PRENOM.like(" -%"))))
.and(evenement.IDPERS.isNotNull())
.and(lieu.LIBELLE.isNotNull())
.and(genealogie.STATUS.ge(Byte.valueOf("1")))
.and(personne.CONTEMPORAIN.eq(Byte.valueOf("0"))))
.groupBy(evenement.IDGROUPE2)
.fetch();
System.out.println("countRs group2Rs libellesRs");
System.out.println("---------------------------");
for (Record r : result) {
System.out.println(r.get("countRs")+" "+r.get("group2Rs")+" "+r.get("libelleRs"));
}
try {
create.close();
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
As you can see it's basicly just opening the connection with the database, making a query and closing the connection/query, nothing special.
But when i check the client connections to my database using MySQL Workbench i can see that my code opened 10 connection:
And as you can see, only a single one of these connections is actualy executing the query.
Is there something i don't know about how JOOQ executes queries? Or mabe it is because i'm using Putty to access my remote server and it somehow creates many connections?
Since you're using HikariCP in your project, you should not create new connections manually using DriverManager:
// Don't do this
connection = DriverManager.getConnection(url, user, password);
DSLContext create = DSL.using(connection, SQLDialect.MYSQL);
Instead, use HikariCP as a DataSource and pass that to jOOQ:
// Do this
DSLContext create = DSL.using(dataSource, SQLDialect.MYSQL);
Now, you don't have to do any resource management anymore, because jOOQ / Hikari do this for you, behind the scenes (i.e. no close() calls)

jdbc mysql driver not found after deploying

I have developed a REST application using jersey where to connect to database(mysql) I use jdbc connection. Following is the configuration.
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/DBNAME";
static final String USER = "root";
static final String PASS = "********";
public List<Item> getAll() {
List<Item> results = new ArrayList<>();
try (Connection conn = (Connection) DriverManager.getConnection(DB_URL,
USER, PASS);
Statement stmt = (Statement) conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM items");) {
while (rs.next()) {
// Retrieve by column name
System.out.println(rs.getInt("ID"));
System.out.println(rs.getString("FormerCode"));
System.out.println(rs.getString("NewCode"));
results.add(new Item(rs.getInt("ID"), rs
.getString("FormerCode"), rs.getString("NewCode")));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return results;
}
All things works when I deploy via Eclipse. But when I create the war file and deploy it manually on tomcat server it gets the exception saying there is no suitable driver.
No suitable driver found for 'jdbc:mysql://localhost:3306/DBNAME
I have included the mysql-connector jar files in both WEB-INF/lib folder and TOMCAT_HOME/lib folder. But I am still getting this error. Server is running on Ubuntu Server 14.04.
Paths where jar is added.
src/main/webapp/WEB-INF/lib
usr/share/tomcat7/lib
What seems to be the problem hence I have added the jar files to necessary locations??
Sometimes java class failed to pick driver's(mysql java connector jar file) path from lib folder. To remove this issue you can extract connector jar in following directory of your project.
src/main/webapp/WEB-INF/classes
OR
You may also compile the java file with classpath reference of mysql_java_connector.jar.
The answer was when using a DriverManager interface to create a JDBC Connection, always create an instance of your JDBC driver first in order to load it into your Classloader.
try {
// The newInstance() call is a work around for some
// broken Java implementations
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (Exception ex) {
// handle the error
}
Thanks all.

When working with tomcat, how are JDBC Drivers loaded?

I am using Eclipse and tomcat 7. I have little experience with either product and for that matter Java itself. I was trying to connect to a derby database from a Servlet. Initially, all I had in my doGet() is the following:
conn = DriverManager.getConnection(connectionURL);
I have connectionURL defined as
static private String connectionURL = "jdbc:derby://localhost:1527/seconddb";
Then I added the following to the Build Path and Deployment Assembly.
C:\DERBY\db-derby-10.10.1.1-bin\lib\derbyclient.jar
That is all I did. I sort of assumed that Tomcat will find the driver class and load it. I got the following error
java.sql.SQLException: No suitable driver found for jdbc:derby://localhost:1527/seconddb
Then I went on to add the following code in doGet() to load the driver class:
try {
Class.forName("org.apache.derby.jdbc.ClientDriver");
}
catch(ClassNotFoundException ex) {
System.out.println("Error: unable to load driver class!");
System.exit(1);
}
Now it worked. I thought that after Java 1.4 there was no need to explicitly load JDBC driver class. So what am I doing wrong here? I have given the entire code below.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Connection conn = null;
try {
Class.forName("org.apache.derby.jdbc.ClientDriver");
}
catch(ClassNotFoundException ex) {
System.out.println("Error: unable to load driver class!");
System.exit(1);
}
try {
conn = DriverManager.getConnection(connectionURL);
//DriverManager.getConnection("jdbc:derby://localhost:1527/testdb;create=true");
}
catch (SQLException e) {
e.printStackTrace();
}
PrintWriter p = response.getWriter ();
p.println("Connected to database");
try {
if (conn != null) {
conn.close();
}
}
catch (SQLException e) {
e.printStackTrace();
}
}
I am using java 1.7
I cannot really explain why, but here is how I do :
if the driver is located in the war, I must call Class.forName("...Driver"); in in initialization method somewhere in the web application.
if the driver is located in Tomcat libraries, it is automacally loaded when I need it.
I know it's more a rule of thumb than a clear explaination, but my knowledge in class loading does not allow me to a better answer ...
Your Derby driver doesn't support the JDBC 4 auto-loading, so you have to do it manually. Try to find a more up to date version.
I could be wrong here but in your second code sample connectionURL
static private String connectionURL = "jdbc:derby://localhost:1527/seconddb";
doesn't include "create=true"; to complete the statement. In your full code sample it's included, but commented out.

JDBC not connecting

While the build paths are not correct I obtain “com.microsoft.sqlserver.jdbc.SQLServerDriver” from the stack trace. As they are built correctly, I obtain my printed statement “Successfully connected”. The JDBC is living within the getter/setters of the webservice as a method.
When I place the JDBC content in its own file with no builds and run as a java application I receive: “com.microsoft.sqlserver.jdbc.SQLServerDriver”
When I place the JDBC content in its own file with builds and run as a java application I receive: “Successfully connected”
When the method is called from a test file as a java application I receive: “Successfully connected”
Ex:
public static void main(String[] args) {
insert.main(args);
When the method is run as a java application on PO I receive: “Successfully connected”
When I place the method to be called under a setter (which will be invoked by the client, which will cause the jdbc to be invoked) I receive: “com.microsoft.sqlserver.jdbc.SQLServerDriver”
Would you happen to have any tips for me? I’m clueless why it will work under being invoked as an application but not via client?
public class insert{
public static void main(String[] args) {
Connection con = null;
Statement st = null;
final String DB_URL = "jdbc:jtds:sqlserver://00.00.00.00:0000/DB";
// Database credentials
final String USER = "usrname";
final String PASS = "pw";
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection(DB_URL, USER, PASS);
st = con.createStatement();
System.out.println("successfully connected!");
} catch (Exception err) {
System.out.println(" " + err.getMessage ());
}
finally {
try {
con.close();
} catch (Exception e) { /* ignored */ }
try {
st.close();
} catch (Exception e) {
/* ignored */
}
}
}
}
Any tips at this point would be greatly appreciated.
The problem is that your jar misses the necessary libraries that provides com.microsoft.sqlserver.jdbc.SQLServerDriver class and others to communicate with your SQL server. You have to make sure the library is loaded and available when is being executed from tomcat. Just copy your library and drop it inside %TOMCAT_INSTALL%/lib folder, where %TOMCAT_INSTALL% is the folder where your tomcat is installed, so the library will be available for every project (war, jar, etc) that runs in your tomcat installation.

Why can't I get a remote data source within an applet?

I trying to do a JNDI lookup on a data source that lives in Weblogic 10.3.5.
I have the following code:
try {
//jbInit();
env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
env.put(javax.naming.Context.PROVIDER_URL,"t3://localhost:7001");
try {
Context ctx = new InitialContext(env);
javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup("jdbc/sandboxDS");
conn = ds.getConnection();
} catch(Exception e){
e.printStackTrace();
}
if(conn != null){
System.out.println("Got connection...");
String colDescQuery =
"select column1 from my_table where table_name = 'your_table' order by col_order_no";
Statement colDescStmt = conn.createStatement();
ResultSet colDescRS = colDescStmt.executeQuery(colDescQuery);
while (colDescRS.next()) {
System.out.println(colDescRS.getString(1));
}
} else {
System.out.println("No connection...");
}
} catch (Exception e) {
e.printStackTrace();
}
When I run this code as a stand alone Java program it works perfectly. The connection is found and the query returns the expected results.
When I use the same code in an applet and run it from the JDeveloper applet viewer it hangs where the InitialContext is instantiated. No exceptions are thrown, it simply hangs never to return.
Any ideas as to what is going on here? I have weblogic.jar and wlthint3client.jar in my classpath for both runs.
Thanks...
Applets have sandbox restrictions, so they cannot connect to the server other than where they were downloaded from.
Make sure your applet is also deployed to the same WebLogic Server that your JNDI data source is on.

Categories