glassfish
  1. glassfish
  2. GLASSFISH-15443

NullPointerException in com.sun.enterprise.resource.pool.PoolManagerImpl.getJavaName

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.1_b33
    • Fix Version/s: 3.1_b38
    • Component/s: jdbc
    • Labels:
      None
    • Environment:

      Linux

      Description

      calling getConnection on a DataSource results in an intermittent NullPointerException in getJavaName as follows:

      com.sun.enterprise.resource.pool.PoolManagerImpl.getJavaName(PoolManagerImpl.java:539)
      com.sun.enterprise.resource.pool.PoolManagerImpl.getResourceReference(PoolManagerImpl.java:530)
      com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:175)
      com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:165)
      com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:160)
      com.sun.gjc.spi.base.DataSource.getConnection(DataSource.java:110)
      com.kickstone.pricegoblin.data.goblin.GoblinData.getProduct(GoblinData.java:173)
      ...

      where the calling class is defined as:
      @ManagedBean
      public class GoblinData {
      ...
      public void getProduct(URI uri){
      ...
      Retailer retailer=null;
      try

      { retailer=(Retailer)em.createNamedQuery("Retailer.findByExternalUri").setParameter("externalUri", externalUri).getSingleResult(); }

      catch (NoResultException ex)

      { return; // TODO - retailer not matched }

      ...
      try {
      Connection c=null;
      try

      { c=ds.getConnection(); ... }

      finally

      { if (c!=null) c.close(); }

      } catch (SQLException ex){
      }
      }

      @PersistenceContext(unitName="PriceGoblinPU")
      private EntityManager em;

      @Resource(mappedName="jdbc/frontendDB")
      private DataSource ds;
      }

      and the datasource is defined as:

      <jdbc-connection-pool validation-table-name="connection_validation" pool-resize-quantity="2" datasource-classname="org.postgresql.ds.PGSimpleDataSource" max-pool-size="32" wrap-jdbc-objects="false" res-type="javax.sql.ConnectionPoolDataSource" steady-pool-size="2" description="PostgreSql" name="FrontendDB">
      <property name="PortNumber" value="xxx"></property>
      <property name="Password" value="xxx"></property>
      <property name="ServerName" value="xxx"></property>
      <property name="DatabaseName" value="xxx"></property>
      <property name="User" value="xxx"></property>
      </jdbc-connection-pool>
      <jdbc-resource pool-name="FrontendDB" jndi-name="jdbc/frontendDB"></jdbc-resource>

      Looking at the code, the only time logicalName is null (which is passed to getJavaName) is when an entityManager is used, if a DataSource is injected, it is always set.

      If you require any more info, then let me know

        Activity

        Hide
        jsl123 added a comment -

        Hi, I've attached a test case that demonstrates the problem on my machine running pretty much a vanilla Glassfish v3.1.36 install. I've stripped out everything from my main project that doesn't seem to be needed.

        I don't follow the schema of your testcase as my classes are managed beans and the datasource is injected by the container, finally the multiple references are in separate classes and have different logicalNames - see below for details of testcase

        I only use the datasource.getConnection so that I can generate Arrays which are vendor specific. The tables, database settings will need changing to meet your needs, otherwise it should be fairly straightforward. The project includes a jmeter test which causes the problem about 1 in 500 hits although you need to heavily load it to get a failure so ramping up of the settings may be needed - equally I could only see the error when not in the debugger...

        The project contains the following features which seem to contribute to the problem:

        • Uses Jersey Rest implementation with 2 resource entry points - home and product. The latter is to be called and generates the error.
        • the Datasource is injected into 2 different classes (home & goblindata) which result in the 2 distinct references in getResourceReference. The logical name is a concatenation of the class and member name, the jndi name is as expected.
        • I use an entity Manager (based on a persistenceUnit using the same database resource) as well as this seems to have null for the logicalName, in addition its jdni name has _nontx appended - which I found confusing.
        • all the classes used are managed by the container (CDI beans)

        The test case doesn't really do anything, although as it stands the first db call should succeed in order to get the connection and trigger the error.

        Let me know if you have any problems (or I've done something stupid in my implementation)

        Show
        jsl123 added a comment - Hi, I've attached a test case that demonstrates the problem on my machine running pretty much a vanilla Glassfish v3.1.36 install. I've stripped out everything from my main project that doesn't seem to be needed. I don't follow the schema of your testcase as my classes are managed beans and the datasource is injected by the container, finally the multiple references are in separate classes and have different logicalNames - see below for details of testcase I only use the datasource.getConnection so that I can generate Arrays which are vendor specific. The tables, database settings will need changing to meet your needs, otherwise it should be fairly straightforward. The project includes a jmeter test which causes the problem about 1 in 500 hits although you need to heavily load it to get a failure so ramping up of the settings may be needed - equally I could only see the error when not in the debugger... The project contains the following features which seem to contribute to the problem: Uses Jersey Rest implementation with 2 resource entry points - home and product. The latter is to be called and generates the error. the Datasource is injected into 2 different classes (home & goblindata) which result in the 2 distinct references in getResourceReference. The logical name is a concatenation of the class and member name, the jndi name is as expected. I use an entity Manager (based on a persistenceUnit using the same database resource) as well as this seems to have null for the logicalName, in addition its jdni name has _nontx appended - which I found confusing. all the classes used are managed by the container (CDI beans) The test case doesn't really do anything, although as it stands the first db call should succeed in order to get the connection and trigger the error. Let me know if you have any problems (or I've done something stupid in my implementation)
        Hide
        Jagadish added a comment - - edited

        Thanks for sharing the test-case, I tried the test-case using jmeter and could not reproduce it in varied load, multiple times.

        • I tried it using Derby (create a jdbc-resource named jdbc/frontendDB
          asadmin create-jdbc-resource --connectionpoolid DerbyPool jdbc/frontendDB
        • DDL :
          create table retailer_retailer ( id integer primary key, date_created date, last_modified date, external_uri varchar(100), name varchar(50), description varchar(200))

        > I use an entity Manager (based on a persistenceUnit using the same database
        > resource) as well as this seems to have null for the logicalName, in addition its jdni
        > name has _nontx appended - which I found confusing.

        Yes, JPA uses the resource (in persistence.xml) which will account for physical lookup with __nontx suffix which is for internal purposes to get a non-transactional connection. This is expected.

        > the Datasource is injected into 2 different classes (home & goblindata) which result in
        > the 2 distinct references in getResourceReference
        Yes, since these are defined in the .war, all of the resource-references (@Resource) will be shared within the jndi environment of the .war.

        Show
        Jagadish added a comment - - edited Thanks for sharing the test-case, I tried the test-case using jmeter and could not reproduce it in varied load, multiple times. I tried it using Derby (create a jdbc-resource named jdbc/frontendDB asadmin create-jdbc-resource --connectionpoolid DerbyPool jdbc/frontendDB DDL : create table retailer_retailer ( id integer primary key, date_created date, last_modified date, external_uri varchar(100), name varchar(50), description varchar(200)) > I use an entity Manager (based on a persistenceUnit using the same database > resource) as well as this seems to have null for the logicalName, in addition its jdni > name has _nontx appended - which I found confusing. Yes, JPA uses the resource (in persistence.xml) which will account for physical lookup with __nontx suffix which is for internal purposes to get a non-transactional connection. This is expected. > the Datasource is injected into 2 different classes (home & goblindata) which result in > the 2 distinct references in getResourceReference Yes, since these are defined in the .war, all of the resource-references (@Resource) will be shared within the jndi environment of the .war.
        Hide
        jsl123 added a comment -

        Hi, do you have a matching entry in the retailer table to the url passed into the rest method? Otherwise as the code stands it will drop out and therefore doesn't create the connection explictly from the Datasource which is what results in the error. For reference, the error happens on line 45 in GoblinData.java.

        You may also need to create another table:

        CREATE TABLE django.summary_map (
        id integer primary key,
        offer_id integer,
        template integer,
        position integer,
        value character varying
        )

        which is used, although I only use a query against it so merged the query into the retailer entity object so you may not have spotted it...

        Show
        jsl123 added a comment - Hi, do you have a matching entry in the retailer table to the url passed into the rest method? Otherwise as the code stands it will drop out and therefore doesn't create the connection explictly from the Datasource which is what results in the error. For reference, the error happens on line 45 in GoblinData.java. You may also need to create another table: CREATE TABLE django.summary_map ( id integer primary key, offer_id integer, template integer, position integer, value character varying ) which is used, although I only use a query against it so merged the query into the retailer entity object so you may not have spotted it...
        Hide
        Jagadish added a comment -

        How bad is its impact? (Severity)

        • Likely to generate a customer support call
          How often does it happen? (Frequency)
        • Whenever multiple "resource-ref" or @Resource injections for same resource happens and the component also does physical lookup of the resource (rather than injection).

        How much effort is required to fix it? (Cost)

        • Fix is to introduce not null check for logicalName so that this issue is avoided.

        What is the risk of fixing it? (Risk)

        • Minimal as it happens in the above use-case and the fix is localized to this specific use-case.

        Does a work around for the issue exist? Can the workaround be reasonably employed by the end user?

        • For this particular use-case, no workaround exists. Only option for the user is to change the code to avoid doing physical lookup which might be difficult.

        If the issue is not fixed should the issue and its workaround (if applicable) be described in the Release Notes?

        • N.A

        All tests passed : QL (Web, Classic), connector-dev, jdbc-dev, connector-standalone-cts (Web, Classic), resources-admin-cli and the use-case I have posted.
        Since I could not reproduce the exact setup by the bug-submitter, requested bug-submitter to test the fix and got confirmation that the fix resolves the issue for him.

        Will also add a dev-test for this scenario.

        Show
        Jagadish added a comment - How bad is its impact? (Severity) Likely to generate a customer support call How often does it happen? (Frequency) Whenever multiple "resource-ref" or @Resource injections for same resource happens and the component also does physical lookup of the resource (rather than injection). How much effort is required to fix it? (Cost) Fix is to introduce not null check for logicalName so that this issue is avoided. What is the risk of fixing it? (Risk) Minimal as it happens in the above use-case and the fix is localized to this specific use-case. Does a work around for the issue exist? Can the workaround be reasonably employed by the end user? For this particular use-case, no workaround exists. Only option for the user is to change the code to avoid doing physical lookup which might be difficult. If the issue is not fixed should the issue and its workaround (if applicable) be described in the Release Notes? N.A All tests passed : QL (Web, Classic), connector-dev, jdbc-dev, connector-standalone-cts (Web, Classic), resources-admin-cli and the use-case I have posted. Since I could not reproduce the exact setup by the bug-submitter, requested bug-submitter to test the fix and got confirmation that the fix resolves the issue for him. Will also add a dev-test for this scenario.
        Hide
        Jagadish added a comment -

        svn log -v -r 44427

        Modified Paths:
        ---------------
        trunk/v3/connectors/connectors-runtime/src/main/java/com/sun/enterprise/resource/pool/PoolManagerImpl.java

        Also added a test-case : refer README
        svn log -v -r 44429
        Modified Paths:
        ---------------
        trunk/v2/appserv-tests/devtests/jdbc/connsharing/nonxa/ejb/SimpleSession.java
        trunk/v2/appserv-tests/devtests/jdbc/connsharing/nonxa/descriptor/ejb-jar.xml
        trunk/v2/appserv-tests/devtests/jdbc/connsharing/nonxa/ejb/SimpleSessionBean.java
        trunk/v2/appserv-tests/devtests/jdbc/connsharing/nonxa/client/Client.java
        trunk/v2/appserv-tests/devtests/jdbc/connsharing/nonxa/README

        Show
        Jagadish added a comment - svn log -v -r 44427 Modified Paths: --------------- trunk/v3/connectors/connectors-runtime/src/main/java/com/sun/enterprise/resource/pool/PoolManagerImpl.java Also added a test-case : refer README svn log -v -r 44429 Modified Paths: --------------- trunk/v2/appserv-tests/devtests/jdbc/connsharing/nonxa/ejb/SimpleSession.java trunk/v2/appserv-tests/devtests/jdbc/connsharing/nonxa/descriptor/ejb-jar.xml trunk/v2/appserv-tests/devtests/jdbc/connsharing/nonxa/ejb/SimpleSessionBean.java trunk/v2/appserv-tests/devtests/jdbc/connsharing/nonxa/client/Client.java trunk/v2/appserv-tests/devtests/jdbc/connsharing/nonxa/README

          People

          • Assignee:
            Jagadish
            Reporter:
            jsl123
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: