This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 78690 - Netbeans/Derby/Tomcat do not play together
Summary: Netbeans/Derby/Tomcat do not play together
Status: RESOLVED INVALID
Alias: None
Product: db
Classification: Unclassified
Component: Derby (show other bugs)
Version: 5.x
Hardware: PC Linux
: P3 blocker (vote)
Assignee: Andrei Badea
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-06-20 23:11 UTC by ajacobs3
Modified: 2006-07-24 11:00 UTC (History)
0 users

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description ajacobs3 2006-06-20 23:11:58 UTC
The problem is the way Derby is bundled with Application Server.

META-INF/context.xml
====================
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/DBConnect" docBase="DBConnect" reloadable="true"
    crossContext="true">
    <!-- Resource name="jdbc/oraDB"
      auth="Container" type="javax.sql.DataSource"
      maxActive="100" maxIdle="30" maxWait="10000"
      username="ajacobs" password="tomcat"
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://localhost:3306/test?autoReconnect=true"/ -->
    <Resource name="jdbc/oraDB"
      auth="Container" type="javax.sql.DataSource"
      maxActive="100" maxIdle="30" maxWait="10000"
      username="app" password="app"
      driverClassName="org.apache.derby.jdbc.ClientDriver"
      url="jdbc:derby://localhost:1527/test"/>
</Context>

WEB-INF/web.xml
===============
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <description>A database connection test.</description>
    <display-name>Database Connection Test</display-name>
    <servlet>
        <servlet-name>DBConnect</servlet-name>
        <servlet-class>com.sun.dbcheck.DBConnect</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DBConnect</servlet-name>
        <url-pattern>/DBConnect</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
	<welcome-file>
            index.jsp
        </welcome-file>
    </welcome-file-list>
    <resource-ref>
        <res-ref-name>jdbc/oraDB</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>
</web-app>

src/com/sun/dbcheck/DBConnect.java
==================================
/*
 * DBConnect.java
 *
 * Created on June 18, 2006, 8:35 PM
 */
package com.sun.dbcheck;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
 *
 * @author ajacobs
 * @version
 */
public class DBConnect extends HttpServlet {
    /** Processes requests for both HTTP <code>GET</code> and <code>POST</code>
methods.
     * @param request servlet request
     * @param response servlet response
     */
    protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
    throws ServletException, IOException {
        java.sql.ResultSet rs = null;
        java.sql.Statement s = null;
        java.sql.Connection conn = null;
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Servlet DBConnect</title>");
        out.println("</head>");
        out.println("<body>");
        try {
            javax.naming.Context initCtx = new javax.naming.InitialContext();
            javax.naming.Context envCtx = (javax.naming.Context)
initCtx.lookup("java:comp/env");
            javax.sql.DataSource ds = (javax.sql.DataSource)
envCtx.lookup("jdbc/oraDB");
            conn = ds.getConnection();
            s = conn.createStatement();
            s.execute("SELECT * From EMPLOYEE");
            out.print("SELECT * From EMPLOYEE<br>");
            rs = s.getResultSet();
            while (rs.next()) {
                out.println(rs.getString("UserName"));
            }
            rs.close();
            rs = null;
            s.close();
            s = null;
            conn.close();
            conn = null;
            out.println("Connection closed");
        } catch (Exception ex) {
            ex.printStackTrace();
            out.println(ex.getMessage()+"<br>");
        } finally {
            if (rs != null) {
                try { rs.close(); } catch (java.sql.SQLException e) { }
                rs = null;
            }
            if (s != null) {
                try { s.close(); } catch (java.sql.SQLException e) { }
                s = null;
            }
            if (conn != null) {
                try { conn.close(); } catch (java.sql.SQLException e) { }
                conn = null;
            }
        }
        out.println("</body>");
        out.println("</html>");
        out.close();
    }
    
    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on
the + sign on the left to edit the code.">
    /** Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
    /** Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
    /** Returns a short description of the servlet.
     */
    public String getServletInfo() {
        return "Short description";
    }
    // </editor-fold>
}

Procedure:
==========
Become root user.
% DERBY_INSTALL=/opt/SUNWappserver/javadb
% export DERBY_INSTALL
% NB_INSTALL=/opt/netbeans-5.5beta
% CATALINA_HOME=${NB_INSTALL}/enterprise3/apache-tomcat-5.5.16
% cd ${CATALINA_HOME}/common/lib
% cp ${DERBY_INSTALL}/lib/derbyclient.jar ${CATALINA_HOME}/common/lib
% cp ${DERBY_INSTALL}/lib/derbytools.jar ${CATALINA_HOME}/common/lib

Add a user to ${CATALINA_HOME}/common/lib/tomcat-users.xml with the
role manager.

% ${CATALINA_HOME}/bin/startup.sh
% cd ${DERBY_INSTALL}/frameworks/NetworkServer/bin
% . ./setNetworkServerCP.ksh
% ./startNetworkServerCP.ksh

In another window, again as root

% DERBY_INSTALL=/opt/SUNWappserver/javadb
% export DERBY_INSTALL
% cd ${DERBY_INSTALL}/frameworks/NetworkServer/bin
% . ./setNetworkClientCP.ksh
% ./ij.ksh
> CONNECT jdbc:derby://localhost:1527/test\;create=true;
> CREATE TABLE EMPLOYEE (
    USERNAME VARCHAR(31) PRIMARY KEY,
    PASSWORD VARCHAR(31) NOT NULL,
    FIRSTNAME VARCHAR(31) NOT NULL,
    LASTNAME VARCHAR(31) NOT NULL,
    DEPT VARCHAR(31) NOT NULL,
    EMPDATE DATE NOT NULL,
    EMAILADDR VARCHAR(31) NOT NULL,
    MODDATE TIMESTAMP NOT NULL
   );
> INSERT INTO EMPLOYEE
  (USERNAME,PASSWORD,FIRSTNAME,LASTNAME,DEPT,EMPDATE,EMAILADDR,MODDATE) VALUES (
  'larry','imlarry','Larry','Fine','comedy','1934-04-01','larry@heaven.org',
  '1975-04-01 00:00:00');
> INSERT INTO EMPLOYEE
  (USERNAME,PASSWORD,FIRSTNAME,LASTNAME,DEPT,EMPDATE,EMAILADDR,MODDATE) VALUES (
  'moe','immoe','Moe','Howard','comedy','1934-04-01','moe@heaven.org',
  '1975-04-05 00:00:00');
> INSERT INTO EMPLOYEE
  (USERNAME,PASSWORD,FIRSTNAME,LASTNAME,DEPT,EMPDATE,EMAILADDR,MODDATE) VALUES (    
  'curly1','imcurly1','Jerome','Howard','comedy','1934-04-01',
  'curly1@heaven.org','1975-01-25 00:00:00');
> INSERT INTO EMPLOYEE
  (USERNAME,PASSWORD,FIRSTNAME,LASTNAME,DEPT,EMPDATE,EMAILADDR,MODDATE) VALUES (
  'curly2','imcurly2','Joseph','Wardell','comedy','1958-04-01',
  'curly2@heaven.org','1993-07-04 00:00:00');
> INSERT INTO EMPLOYEE
  (USERNAME,PASSWORD,FIRSTNAME,LASTNAME,DEPT,EMPDATE,EMAILADDR,MODDATE) VALUES (
  'shemp1','imshemp1','Shemp','Howard','comedy','1934-04-01',
  'shemp1@heaven.org','2005-11-24 00:00:00');
> INSERT INTO EMPLOYEE
  (USERNAME,PASSWORD,FIRSTNAME,LASTNAME,DEPT,EMPDATE,EMAILADDR,MODDATE) VALUES (
  'shemp2','imshemp2','Joe','Besser','comedy','1955-04-01',
  'shemp2@heaven.org','1988-03-02 00:00:00');
> exit;

Clean and compile the application, bundle it in a war file DBConnect.jar.
Bring up the Tomcat manager by using a browser to navigate to
    http://localhost:8080/manager/html
Deploy DBConnect.war.
Run the application using the URL http://localhost:8080/DBConnect/DBConnect
This will work.

Now use the Explorer (Runtime tab).  In the tree Servers->Drivers->JavaDB (Net),
attempt to create a database connection to the URL
jdbc:derby://localhost:1527/test .  The error message is 
"Unable to add connection, cannot establish a connection to
jdbc:derby://localhost:1527/test using org.apache.derby.jdbc.ClientDriver
(java.security.PrivilegedActionException: Error opening socket to server
localhost on port 1527 with message:null)."

Next, shut down the Derby network server.
${DERBY_INSTALL}/frameworks/NetworkServer/bin/stopNetworkServerCP.ksh

Use the Application Server Admin UI to create a Connection Pool
named OraPool of type javax.sql.DataSource and
class name org.apache.derby.jdbc.ClientDataSource.  Set the
user to 'app', password to 'app', server name to 'localhost', port to 1527,
and ConnectionAttributes to ';create=true'.  Create a JDBC/Resource
named 'jdbc/oraDB' that uses this pool.

Next, recursively change the ownership of all files and directories
of /opt/SUNWappserver to a user and group other than root.
Then, as that user, get Netbeans to start Application Server.  Attempt
to create a new database connection to the URL
jdbc:derby://localhost:1527/test .  The
error message is the same as before.  The standard output records
"Exception in thread "main" java.lang.NoClassDefFoundError:
 org/apache/derby/drda/NetworkServerControl"
Shut down the App Server and exit Netbeans.

Next, change the ownership of /opt/SUNWappserver back to root:root.
Start up Netbeans as root.  Get Netbeans to start Application Server.  Attempt
to create a new database connection to the URL
jdbc:derby://localhost:1527/test .  This will still fail.
Attempt to create a new database connection to the URL
jdbc:derby://localhost:1527/test;create=true.  The connection will be made.
Open up the connection node and check the "Tables" node.  It will be
empty.

Disconnect, shut down the App Server and exit Netbeans.
Comment 1 Andrei Badea 2006-06-30 19:49:21 UTC
Sorry, this is too much information and I don't understand what is the real
problem. As far as I understand you can't connect to a database server running
as root from a NetBeans instance running as a non-privileged user. Not clear how
you installed NetBeans -- as root or as a non-privileged user? Did you register
the appserver yourself or did you use a bundle? What is the version of NetBeans? 

Please post steps starting from a clean computer (no appserver, no NetBeans, no
userdir and no .netbeans-javadb or .netbeans-derby directories in the home
directories of the involved users).
Comment 2 Andrei Badea 2006-07-21 15:35:03 UTC
No reply from submitter, marking as incomplete until the required information is
provided.
Comment 3 ajacobs3 2006-07-21 15:55:24 UTC
The point of the bug is that you can't connect to a database server running
as root from a NetBeans instance running as a non-privileged user.
I installed Netbeans as root.  I tried changing the Netbeans file ownership
to those of a non-privileged user, but that did not help.  I thought this might
be a fix for the problem and that this would save Netbeans developers some
time.  My Netbeans file ownership is back to root right now.
The appserver was registered myself.  It is the current Glassfish download,
which is non-standard -- treat this as a bug w/r to the bundled Tomcat.
What is the version of NetBeans?  Netbeans 5.5 beta 1.
About posting the steps starting from a clean computer (no appserver, no
NetBeans, no userdir and no .netbeans-javadb or .netbeans-derby directories
in the home) the answer is no -- I'm using Netbeans for code development.
There is more than sufficient information to replicate the problem.
Comment 4 Andrei Badea 2006-07-21 18:46:16 UTC
I tried to reproduce using the following steps:

1. Installed GlassFish to /opt/glassfish with ownership root:root, file access
rights 644 and directory access rights 2744.

2. Installed NetBeans 5.5 (self-compiled build from Jul 18) to /opt/netbeans-5.5
with same ownership and rights as for GlassFish.

3. As root:

# cd /opt/glassfish/javadb
# export DERBY_INSTALL=$PWD
# cd frameworks/NetworkInstall/bin
# . ./setNetworkServerCP.ksh
# ksh startNetworkServer.ksh

4. As root in another window:

# /opt/netbeans-5.5/bin/netbeans

5. In NetBeans registered GlassFish from /opt/glassfish. This registers the Java
DB database and its drivers.

6. Right-clicked Runtime/Databases/Drivers/Java DB (Network), chose Connect
Using, filled jdbc:derby://localhost/test;create=true, no user, no password.
Pressed OK. Connected successfully, connection was added to the Runtime tab.

7. As an unprivileged user:

$ /opt/netbeans-5.5/bin/netbeans

8. Registered GlassFish, created a personal domain in ~/.glassfish-domain. This
registered the Java DB database and its drivers.

9. Same as step 6, no error encountered.

So sorry, but I'm not able to reproduce. Am I missing something? Are your steps
different?

Seems the real issue here is the "java.security.PrivilegedActionException: Error
opening socket to server localhost" exception. I have managed to reproduce that
only by changing /etc/hosts from

127.0.0.1   localhost    abadea

to

127.0.0.1   localhost

and connection jdbc:derby://abadea/test from a restarted NetBeans. And I can of
course reproduce it when the server is not running.

Could you please try to do

$ telnet localhost 1527

as an unprivileged user while Derby is running as root?
Comment 5 ajacobs3 2006-07-21 21:19:49 UTC
Console 1
# $JAVA_HOME/bin/java \
 -Djava.security.policy=\
 /opt/SUNWappserver/javadb/frameworks/NetworkServer/conf/nwsvr.policy \
 org.apache.derby.drda.NetworkServerControl \
 start -h localhost -p 1527
Server is ready to accept connections on port 1527.
Connection number: 1.

Console 2
% telnet localhost 1527
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Your step #8: "Registered GlassFish, created a personal
domain in ~/.glassfish-domain. This registered the Java DB database and its
drivers."  I skipped this step.  Normally registration is about tracking
customers and has no functional consequences.



registered the Java DB database and its drivers.
Comment 6 ajacobs3 2006-07-21 22:41:43 UTC
I added the database driver again (location
opt/SUNWappserver/javadb/lib/derbyclient.jar and class
org.apache.derby.jdbc.ClientDriver) and connected using the URL
jdbc:derby://localhost:1527/example;create=true with user app.
This worked.  Close the bug.

The difference is probably in the "example" in the JDBC URL.  I think
this is called a "database name" in Derby-speak.  I fussed with any number of
things before this success.

The database has to be started up by root, at least the way I've installed it.
The Netbeans Tools->JavaDB Database->Start JavaDB Server menu item did
not work.

Comment 7 Andrei Badea 2006-07-24 11:00:08 UTC
Closing then. It is weird that Start Java DB Server doesn't work for you though.
Did you register[1] GlassFish in NetBeans? Are the Java DB Location and Database
Location fields in Options - Advanced Options - Servers and External Tool
Settings - Java DB Database set correctly?

[1] by "registered GlassFish" in desc5 I meant "right-clicked Servers in the
Runtime tab, chose Add Server".