Avatar of spetrowitsch
spetrowitsch

asked on 

apache.commons: How to get a DataSource?

Hi,

I plan to hide it for my application to access a "settings"-table or file with two columns: attribute and value.
For that I thought to use apache.commons.

What I did (using a database) until now is getting the connection like this:
        try {
                Class.forName(plmSettingsDBDriver);
          }    
          catch (ClassNotFoundException cnfe) {
                logger.error("Error while reading database-driver-class", cnfe );
          }
          String url = plmSettingsDBURL;
          String username = plmSettingsUser;
          String password = mySettingsPassword;
          Connection con = DriverManager.getConnection(url, username, password);

and reading the data as usual:

                        con = getPLMSettingsConnection();
              
                      for (int i = 0; i < select.length; i++) {
                          stmt = con.createStatement();
                          String query = "SELECT value FROM settings WHERE ATTRIBUTE = '" +
                                select[i] + "'";
                          ResultSet rs = stmt.executeQuery(query);
                          ...
                         }


Now I would like to replace the reading of data with Connections, Statements and ResultSets with something like this:

   String value = config.getEntry(select[0], "settings");
                      
while config is of type CCommConf, where I defined the following functions:

    private Configuration getConfiguration(String configName) throws Exception {
            ConfigurationFactory factory = new ConfigurationFactory();
               factory.setConfigurationFileName(CONFIGFILE);
               Configuration conf1 = factory.getConfiguration();
               Configuration conf2 = null;
               if (con != null) {
                     conf2 = new DatabaseConfiguration((DataSource)con,
                           "settings", "attribute", "value");
               } else {
                  ConfigurationFactory factory2 = new ConfigurationFactory();
                     factory2.setConfigurationFileName(SETTINGSFILE);
                     conf2 = factory.getConfiguration();
               }

               // Create and initialize the node combiner
            NodeCombiner combiner = new UnionCombiner();

            // Construct the combined configuration
            CombinedConfiguration cc = new CombinedConfiguration(combiner);
            cc.addConfiguration((AbstractConfiguration) conf1, "db");
            cc.addConfiguration((AbstractConfiguration) conf2, "settings");
            
            return cc.getConfiguration(configName);
      }

        /**
       * Constructor without any code
       *
       */
      public CCommConf() {
      }

      /**
       * Set´s the connection for the settings-table, if the
       * settings-table is in a database and not some other kind
       * of storage.
       * @param con Connection
       */
      public void setConnection(Connection con) {
            this.con = con;
      }

   public String getEntry(String entry, String configName) throws Exception {
            String ret = null;
        try {
              config = getConfiguration(configName);
                     if (config.getProperty(entry) != null)
                           ret = config.getProperty(entry).toString();
            } catch (ConfigurationException e) {
                  logger.fatal(e);
                  throw e;
            }
            return ret;
      }


What I don´t know is now:
- How to get a DataSource (I know, the following case is not the right thing to do it: conf2 = new DatabaseConfiguration((DataSource)con, "settings", "attribute", "value"); ). I read somewhere that I have to use JNDI, but - if it´s really necessary - I don´t know how to do that. But maybe it´s not necessary to use JNDI, there is a simpler way?
Java

Avatar of undefined
Last Comment
anokun7
Avatar of anokun7
anokun7

You need to configure the JNDI names on your application server. Its really very simple especially with most application servers which provide a console / web interface for filling in the details.

Once you create a JNDI name that binds (links) to a DataSource which contains the connection pool, you can use code something like this to point to it:

 public static Connection getConnection() {
    Connection dbConnection = null;
    InitialContext ic;
    DataSource dataSource;

    try {
      ic = new InitialContext();
      dataSource = (DataSource) ic.lookup("<THE JNDI NAME>");
      if (dataSource != null) {
        dbConnection = dataSource.getConnection();
      }
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
    return dbConnection;
  }
Avatar of spetrowitsch
spetrowitsch

ASKER

@anokun7

Is it really necessary to make it with an JNDI? In that case, there has to be an application server (and - until now - there is no application server connected with our application, so I would need one just for using jakarta.commons).
Avatar of anokun7
anokun7

ohh - i am sorry - i assumed you were using a j2ee setting.

So - then you do not need a JNDI setup - actually you do not even need a datasource - A datasource is intended to be used with a JNDI context only.

You should be able to get a connection from your connection pool and that would handle creating adequate connections to serve new clients from th pool...

Let me know if my answer is not very clear - I can elaborate.
ASKER CERTIFIED SOLUTION
Avatar of Mayank S
Mayank S
Flag of India image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of rrz
rrz
Flag of United States of America image

>conf2 = new DatabaseConfiguration((DataSource)con, "settings", "attribute", "value");  
You can't use a cast.  I have an idea(hack) that might take you in the right direction. Hopefully the experts will comment. I've never done this before.  You could try to use something like this.  
conf2 = new DatabaseConfiguration( new MyDataSource(), "settings", "attribute", "value");
where we have something like  

  import javax.sql.DataSource;
  import //.... the others needed
  public class MyDataSource implements DataSource
  {
     String username = plmSettingsUser;
     String password = mySettingsPassword;
     String url = plmSettingsDBURL;
     Connection con;
     public MyDataSource() {
                        con = DriverManager.getConnection(url, username, password);    
     }
     public Connection getConnection() throws SQLException{
                        return con;
     }
     public Connection getConnection(String username,String password) throws SQLException{    
     }
     public PrintWriter getLogWriter() throws SQLException{
                      return   ???  ;
     }
     public void setLogWriter() throws SQLException{
     }
     public int getLoginTimeout() throws SQLException{
                        return ???  ;
     public void setLoginTimeout() throws SQLException{
     }
  }
Avatar of spetrowitsch
spetrowitsch

ASKER

I tried to implement something like this:
http://svn.apache.org/viewvc/jakarta/commons/proper/dbcp/trunk/doc/BasicDataSourceExample.java?view=markup

I changed getConfiguration to:
     private Configuration getConfiguration(String configName) throws Exception {
            if (configName.equals("settings")) {
                  if (dbDriver != null) {
                        DataSource ds = setupDataSource();
                           return new DatabaseConfiguration(ds,
                                 "settings", "attribute", "value");
                     } else {
                        ConfigurationFactory factory = new ConfigurationFactory();
                           factory.setConfigurationFileName(SETTINGSFILE);
                           return factory.getConfiguration();
                     }
            }
            return null;
      }

and added the following function:

    private DataSource setupDataSource() throws Exception {
            BasicDataSource ds = null;
            try {
              ds = new BasicDataSource();
              ds.setDriverClassName(dbDriver);
              ds.setUsername(dbUser);
              ds.setPassword(dbPwd);
              ds.setUrl(dbURL);
        } catch (Exception e) {
              throw e;
        }
        return ds;
    }

but when I reach the following line in this function:
ds = new BasicDataSource();

I get this error:
ERROR Following error occurred in method performAction: org/apache/commons/pool/impl/GenericObjectPool, class: ...
   Inner: java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
ERROR org/apache/commons/pool/impl/GenericObjectPool

I tried to import org.apache.commons.pool.impl.GenericObjectPool, but org.apache.commons.pool is not available.
SOLUTION
Avatar of anokun7
anokun7

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
Java
Java

Java is a platform-independent, object-oriented programming language and run-time environment, designed to have as few implementation dependencies as possible such that developers can write one set of code across all platforms using libraries. Most devices will not run Java natively, and require a run-time component to be installed in order to execute a Java program.

102K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo