Thread: problem in connetting using reflection
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
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
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; } }
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