Thread: problem in connetting using reflection

problem in connetting using reflection

From
Giuseppe Sacco
Date:
Hi all,
I am trying to connect to postgresql from a JAVA program.
Previously I used this code:
---------------------------------------------------------------
String classe ="org.postgresql.jdbc3.Jdbc3ConnectionPool";
org.postgresql.jdbc3.Jdbc3ConnectionPool pg;

pg = Class.forName(classe).newInstance();
pg.setServerName(prop.getProperty(serverName));
pg.setPortNumber((new
Integer(prop.getProperty(serverPortNumber)).intValue());
pg.setDatabaseName(prop.getProperty(databaseName));
pg.setUser(login);
pg.setPassword(password);
---------------------------------------------------------------

I then had to change the application in order to use a generic
DataSource (postgresql, oracle, mysql) and noticed that these classes
have different behaviours:
postgreSQL does not have a callable getUrl(), oracle call it getURL,
oracle need a call to getDriverType(), mySQL use setPortNumber(Integer)
instead of setPortNumber(int).

So I tried to use the java reflection to inspect the
org.postgresql.jdbc3.Jdbc3ConnectionPool class (or other classes) and
call all required methods.

The problem is that, when I use this way (a source is attached) I always
get the error:

Exception in thread "main" org.postgresql.util.PSQLException: La
proprietà ``user'' è mancante. E` obbligatoria.
        at
org.postgresql.jdbc1.AbstractJdbc1Connection.openConnection(AbstractJdbc1Connection.java:130)
        at org.postgresql.Driver.connect(Driver.java:138)
        at java.sql.DriverManager.getConnection(DriverManager.java:538)
        at java.sql.DriverManager.getConnection(DriverManager.java:188)
        at
org.postgresql.jdbc2.optional.BaseDataSource.getConnection(BaseDataSource.java:68)
        at
org.postgresql.jdbc2.optional.BaseDataSource.getConnection(BaseDataSource.java:51)
        at
org.postgresql.jdbc3.Jdbc3ConnectionPool.getPooledConnection(Jdbc3ConnectionPool.java:39)
        at dao.jdbc.JDBCMemberDAO.<init>(JDBCMemberDAO.java:29)
        at dao.JDBCDAOFactory.getMemberDAO(JDBCDAOFactory.java:197)
        at test.TestMemberDAO.main(TestMemberDAO.java:34)


that is, in english, "The ``user'' property is missing while it is
mandatory."

Of course the 'setUser()' method is called but it doesn't work.

Do you have any idea about this problem?

I thank you very much,
Giuseppe


Attachment

Re: problem in connetting using reflection

From
Kris Jurka
Date:

On Sun, 11 Apr 2004, Giuseppe Sacco wrote:

> [I want to use reflection to configure a datasource]
>
> Exception in thread "main" org.postgresql.util.PSQLException: La
> propriet� ``user'' � mancante. E` obbligatoria.
>         at
> org.postgresql.jdbc1.AbstractJdbc1Connection.openConnection(AbstractJdbc1Connection.java:130)
>         at org.postgresql.Driver.connect(Driver.java:138)
>         at java.sql.DriverManager.getConnection(DriverManager.java:538)
>         at java.sql.DriverManager.getConnection(DriverManager.java:188)
>         at
> org.postgresql.jdbc2.optional.BaseDataSource.getConnection(BaseDataSource.java:68)
>         at
> org.postgresql.jdbc2.optional.BaseDataSource.getConnection(BaseDataSource.java:51)
>         at
> org.postgresql.jdbc3.Jdbc3ConnectionPool.getPooledConnection(Jdbc3ConnectionPool.java:39)
>         at dao.jdbc.JDBCMemberDAO.<init>(JDBCMemberDAO.java:29)
>         at dao.JDBCDAOFactory.getMemberDAO(JDBCDAOFactory.java:197)
>         at test.TestMemberDAO.main(TestMemberDAO.java:34)
>
>
> that is, in english, "The ``user'' property is missing while it is
> mandatory."
>

You haven't included the code that is actually mentioned in the
stacktrace.  You'll need to either provide the rest of the code in
question or even better a simpler example of the problem you are seeing.

Kris Jurka

Re: problem in connetting using reflection

From
Giuseppe Sacco
Date:
Kris Jurka wrote:
>
> On Sun, 11 Apr 2004, Giuseppe Sacco wrote:
>>[... my error code..]
> You haven't included the code that is actually mentioned in the
> stacktrace.  You'll need to either provide the rest of the code in
> question or even better a simpler example of the problem you are seeing.
>
> Kris Jurka

You are right. Today I made a smaller script, that is attached, and
found my error :-)
Now it works with PostgreSQL, Oracle and mySQL.

Thanks,
Giuseppe
import java.util.Properties;
import java.io.*;
import javax.sql.*;
import java.sql.*;

public class JDBCDAOFactory
{

    static final String datasourceclassname = "org.postgresql.jdbc3.Jdbc3ConnectionPool";
    static final String dbservername = "localhost";
    static final String dbserverportnumber = "5432";
    static final String dbname = "database";

/*
 * It should work with
#
# Oracle
#
#db.dataSourceClassName=oracle.jdbc.pool.OracleConnectionPoolDataSource
#db.servername=localhost
#db.serverportnumber=1521
#
# PostgreSQL
#
db.dataSourceClassName=org.postgresql.jdbc3.Jdbc3ConnectionPool
db.servername=localhost
db.serverportnumber=5432
#
# mySQL
#
#db.dataSourceClassName=gwe.sql.gweMysqlConnectionPoolDataSource
#db.servername=localhost
#db.serverportnumber=3306
 *
 */

    static private ConnectionPoolDataSource connectionPoolDataSource;

    public static void main(String[] args) throws Exception {

    connectToPg("myuser","mypassword");

    /*
     * Now we are supposed to be connected, so create a statement and execute it
     */

    doQuery();
    }

    static void doQuery() throws Exception {

    PooledConnection pooledConn = connectionPoolDataSource.getPooledConnection();
    Statement stmt = pooledConn.getConnection().createStatement();
    ResultSet rs;

    rs = stmt.executeQuery("SELECT CURRENT_DATE");
    stmt.close();
    }

    static void connectToPg(String login, String password) throws Exception {

         Class classe = Class.forName(datasourceclassname);
         Object conDS = classe.newInstance();
         java.lang.reflect.Method metodo;
         Class argomenti[] = new Class[1];
         String args[] = new String[1];

         argomenti[0] = String.class;
         metodo = classe.getMethod("setServerName", argomenti);
         args[0] = dbservername;
         metodo.invoke(conDS, args);

         if (dbserverportnumber != null) {
             Integer iargs[] = new Integer[1];
             iargs[0] = new Integer(dbserverportnumber);

             try {
                 argomenti[0] = Class.forName("java.lang.Integer");
                 metodo = classe.getMethod("setPortNumber", argomenti);
                 metodo.invoke(conDS, iargs);
             }
             catch (Exception e) { /* this only works in mySQL driver */ }

             try {
                 argomenti[0] = int.class;
                 metodo = classe.getMethod("setPortNumber", argomenti);
                 metodo.invoke(conDS, iargs);
             }
             catch (Exception e) { /* this work on all other drivers */ }
         }

         argomenti[0] = String.class;
         metodo = classe.getMethod("setDatabaseName", argomenti);
         args[0] = dbname;
         metodo.invoke(conDS, args);

         try {
             argomenti[0] = String.class;
             metodo = classe.getMethod("setDriverType", argomenti);
             args[0] = "thin";
             metodo.invoke(conDS, args);
         }
         catch (Exception e) { /* funziona solo con oracle e fallisce con gli altri */ }

         argomenti[0] = String.class;
         metodo = classe.getMethod("setUser", argomenti);
         args[0] = login;
         metodo.invoke(conDS, args);

         argomenti[0] = String.class;
         metodo = classe.getMethod("setPassword", argomenti);
         args[0] = password;
         metodo.invoke(conDS, args);

         try {
             metodo = classe.getMethod("getURL", null);
             args[0] = (String)(metodo.invoke(conDS, null));
         }
         catch (Exception e) {
             try {
                 metodo = classe.getMethod("getUrl", null);
                 args[0] = (String)(metodo.invoke(conDS, null));
             }
             catch (Exception ee) {
                 args[0] = null;
             }
         }
         if (args[0] != null)
             System.err.println("getUrl() = " + args[0]);

    connectionPoolDataSource = (ConnectionPoolDataSource)conDS;
    }
}

Re: problem in connetting using reflection

From
Oliver Jowett
Date:
Giuseppe Sacco wrote:

> So I tried to use the java reflection to inspect the
> org.postgresql.jdbc3.Jdbc3ConnectionPool class (or other classes) and
> call all required methods.
>
> The problem is that, when I use this way (a source is attached) I always
> get the error:

> that is, in english, "The ``user'' property is missing while it is
> mandatory."
>
> Of course the 'setUser()' method is called but it doesn't work.
>
> Do you have any idea about this problem?

We use exactly the same technique (set properties by reflection on the
DataSource) and it works fine, so the concept is ok; the problem lies in
your implementation.

Perhaps you are setting the username to an empty string?

-O