1

I have a restful api-implementation running in a Tomcat 8 server. I decided to use the embedded Derby version to store data in a database via JDBC (using Eclipse). From my point of view, the official tutorial for the embedded version wasn't very helpfull. I followed the steps here: http://www.nailedtothex.org/roller/kyle/entry/defining-embedded-derby-as-a

My problem is, that the connection to Derby is not found and since I am using the embedded version for Derby, I don't know how to debug the reason for not connecting to Derby.

I copied the derby.jar and derby-shutdown-listener.jar into the lib folder of my Tomcat server. I adapeted the context.xml and the server.xml.

context.xml:

<Context docBase="myapp"
      path="/myapp"
      reloadable="true">

      <ResourceLink name="jdbc/derby"
              global="jdbc/derby"
              type="javax.sql.DataSource" />
</Context>

I also tried this version of the context.xml:

<Context docBase="myapp"
      path="/myapp"
      reloadable="true">
<Resource name="jdbc/derby" auth="Container"
      driverClassName="org.apache.derby.jdbc.EmbeddedDriver"
      username="bot" password="carmeq!"
      type="javax.sql.DataSource"
      url="jdbc:derby:mydb;create=true"/>
</Context>

server.xml:

 <Listener className="org.nailedtothex.derby.DerbyShutdownLifecycleListener" />

And I changed my web.xml:

   <resource-ref>
    <res-ref-name>jdbc/derby</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
   </resource-ref>

In my Java class concerning the connection to the db, I have the following specification:

String dbURL2 = "jdbc:derby:mydb;create=true";

That is my exception I am receiving when I call my restful function.

javax.servlet.ServletException: java.lang.NullPointerException
    org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:487)
    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

When debugging the code, it shows that no suitable driver for the specified url was found.

Moreover, I am using Maven and beside the derby.jar in my Tomcat folder (showing up under Libraries/Apache Tomcat v8.0), I also added the same derby.jar (Version 10.9.1.0) in my pom.xml.

Thanks

Matzka
  • 125
  • 1
  • 13
  • What do you mean by "the connection to Derby is not found"? Do you get an error message? An exception? Be as precise as you can be about the particular symptom that you experience, and people can help. – Bryan Pendleton Nov 14 '16 at 19:11
  • Hi @BryanPendleton, I added the exception. – Matzka Nov 14 '16 at 21:17
  • I found that discussion: http://stackoverflow.com/questions/3816015/sqlexception-no-suitable-driver-found-for-jdbcderby-localhost1527, but the derby.jar is in the tomcat folder and showing up in the tomcat section of Libraries. Concerning, the url I have tried almost everything.. – Matzka Nov 14 '16 at 22:10
  • Can you add more detail about "debugging the code, it shows that no suitable driver for the specified url was found"? – Bryan Pendleton Nov 15 '16 at 03:07
  • In the java.sql.DriverManager class I am coming to that if scope: // if we got here nobody could connect. if (reason != null) { println("getConnection failed: " + reason); throw reason; } println("getConnection: no suitable driver found for "+ url); throw new SQLException("No suitable driver found for "+ url, "08001"); } – Matzka Nov 15 '16 at 07:44
  • I found the problem: I changed my Java application by subsituting DriverManager.getConnection(url) with the definition of a DataSource and a Context object like it is done here: http://www.nailedtothex.org/roller/kyle/entry/defining-embedded-derby-as-a. Now I can connect to the db! ;-) – Matzka Nov 15 '16 at 15:02

1 Answers1

1

The tomcat original documentation (at least for 8.0) also states, that the author had no luck and the other documentation around in the web is also not so clear. Here is how it works for me...

In server.xml you should have the Resource added within GlobalNamingResources:

<GlobalNamingResources>
  <!-- Keep non DB Resource stuff here ... -->

  <Resource auth="Container" 
    driverClassName="org.apache.derby.jdbc.EmbeddedDriver" 
    maxActive="100" maxIdle="30" maxWait="10000" 
    name="jdbc/myDerby" username="" password="" 
    type="javax.sql.DataSource" 
    url="jdbc:derby:Databases/myDerbyDB;create=true"/>
</GlobalNamingResources>

In context.xml you should Link to it like this:

<ResourceLink name="jdbc/myDerbyLink"
  global="jdbc/myDerby"
  type="javax.sql.DataSource" />

I believe, that putting the Resource itself in context.xml will not work, at least it did not for me.

In your code, the DB is usually accessible as the Link/Reference name, jdbc/myDerbyLink:

Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/myDerbyLink");
Connection conn = ds.getConnection();

If you avoid using the same name for the link's name and global attributes, it can be much less irritiating. Just to make it a bit more clear, here how the links are processed (XPath like):

Java Code "java:/comp/env/<JDBCString>"
  ==> context.xml:/Context/ResourceLink/@name == <JDBCString>
  ==> ./@global == server.xml:/GlobalNamingResources/Resource/@name

In web.xml, not using context.xml, you should be able to use the Resource's short name jdbc/myDerby directly. If not, try using the full one java:/comp/env/jdbc/myDerby.

BTW: It would be also helpful if you paste the piece of code that causes the error.

themole
  • 363
  • 3
  • 12