20

I'm trying to find out why my web application throws a

javax.naming.NameNotFoundException: Name [flexeraDS] is not bound in this Context. Unable to find [flexeraDS].

when a sister one from which I'm copying the configuration quietly runs.

I have:

  1. create from netbeans a new persistence by right clicking and selecting "new persistence", I don't care about the actual values I give but I just need for the persistence.xml file to be created in the right directory.
  2. edited my context.xml as below matching the one from working sister project
  3. edited my web.xml to contain a resource DataSource as shown below
  4. edited my persistence.xml as below again matching the same values which on the sister project work.
  5. added all libraries present in the other project inside the lib folder of mine and adding them also from NetBeans to be correctly put inside war.

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/PetLogin">
  <ResourceLink global="ds/flexeraDS" name="ds/flexeraDS" type="javax.sql.DataSource"/>
</Context>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app ....>
<resource-ref>
        <description>DB Connection</description>
        <res-ref-name>ds/flexeraDS</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
</web-app>

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
             xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd ">
    <persistence-unit name="flexerajpa">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <non-jta-data-source>java:/comp/env/ds/flexeraDS</non-jta-data-source>
        <properties>

            <property name="eclipselink.ddl-generation" value="create-tables" />
            <property name="eclipselink.ddl-generation.output-mode"
                      value="database" />
            <property name="eclipselink.weaving" value="static" />
            <property name="eclipselink.logging.level" value="WARNING" />
        </properties>
    </persistence-unit>
</persistence>

Now my syster project some-how manages to create its database folder inside apache-tomcat-7.0.40/bin/exampleDB on startup while mine doesn't create it and throws an error as above.

The code where the error is thrown is the first time I connect to the database:

EntityManager entityManager = PersistenceProvider.createEntityManager();

where the PersistenceProvider class is:

public final class PersistenceProvider
{

    private static Map<String, Object> lOptions = new HashMap<String, Object>();

    static
    {
        lOptions.put(PersistenceUnitProperties.CACHE_SHARED_DEFAULT, "false");
    }
    private static EntityManagerFactory factory = Persistence
            .createEntityManagerFactory("flexerajpa", lOptions);

    private PersistenceProvider()
    {
    }

    /**
     * @return
     */
    public static EntityManager createEntityManager()
    {
        return factory.createEntityManager();
    }

    /**
     * @return
     */
    public static Metamodel getMetamodel()
    {
        return factory.getMetamodel();
    }
}

I'm out of possible reasons for this.. if anyone has any suggestion. Thank you

dendini
  • 3,842
  • 9
  • 37
  • 74

4 Answers4

15

Ok found out the Tomcat file server.xml must be configured as well for the data source to work. So just add:

<Resource 
auth="Container" 
driverClassName="org.apache.derby.jdbc.EmbeddedDriver" 
maxActive="20" 
maxIdle="10" 
maxWait="-1" 
name="ds/flexeraDS" 
type="javax.sql.DataSource" 
url="jdbc:derby:flexeraDB;create=true" 
  />
rzymek
  • 9,064
  • 2
  • 45
  • 59
dendini
  • 3,842
  • 9
  • 37
  • 74
  • 1
    I thought It is NOT recommended to place elements directly in the server.xml file, as specified in the Apache doc ? – Karen Goh Sep 15 '17 at 10:18
4

You can also add

<Resource 
auth="Container" 
driverClassName="org.apache.derby.jdbc.EmbeddedDriver" 
maxActive="20" 
maxIdle="10" 
maxWait="-1" 
name="ds/flexeraDS" 
type="javax.sql.DataSource" 
url="jdbc:derby:flexeraDB;create=true" 
/> 

under META-INF/context.xml file (This will be only at application level).

rzymek
  • 9,064
  • 2
  • 45
  • 59
Ritesh Kaushik
  • 715
  • 2
  • 13
  • 24
4

In Tomcat 8.0.44 I did this: create the JNDI on Tomcat's server.xml between the tag "GlobalNamingResources" For example:

<GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
  <!-- Other previus resouces -->
    <Resource auth="Container" driverClassName="org.postgresql.Driver" global="jdbc/your_jndi" 
    maxActive="100" maxIdle="20" maxWait="1000" minIdle="5" name="jdbc/your_jndi" password="your_password" 
    type="javax.sql.DataSource" url="jdbc:postgresql://localhost:5432/your_database?user=postgres" username="database_username"/>
  </GlobalNamingResources>
In your web application you need a link to that resource (ResourceLink):

project explore

<?xml version="1.0" encoding="UTF-8"?>
<Context reloadable="true" >
   <ResourceLink name="jdbc/your_jndi"
      global="jdbc/your_jndi"
      auth="Container"
      type="javax.sql.DataSource" />
</Context>

So if you're using Hiberte with spring you can tell to him to use the JNDI in your persistence.xml

persistence.xml location

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
 version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
 <persistence-unit name="UNIT_NAME" transaction-type="RESOURCE_LOCAL">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>

  <properties>
   <property name="javax.persistence.jdbc.driver"   value="org.postgresql.Driver" />
   <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
   
   <!--  <property name="hibernate.jdbc.time_zone" value="UTC"/>-->
   <property name="hibernate.hbm2ddl.auto" value="update" />
   <property name="hibernate.show_sql" value="false" />
   <property name="hibernate.format_sql" value="true"/>     
  </properties>
 </persistence-unit>
</persistence>

So in your spring.xml you can do that:

<bean id="postGresDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiName" value="java:comp/env/jdbc/your_jndi" />
  </bean>
     
        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
              <property name="persistenceUnitName" value="UNIT_NAME" />
              <property name="dataSource" ref="postGresDataSource" />
              <property name="jpaVendorAdapter"> 
                 <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
              </property>
        </bean>
Look above that entityManagerFactory bean refers to your UNIT_NAME configured at persistence xml and the bean postGresDataSource has a property that points to your JNDI resource in Tomcat.

<property name="jndiName" value="java:comp/env/jdbc/your_jndi" />

In this example I used spring with xml but you can do this programmaticaly if you prefer.

That's it, I hope helped.

Rafael Rocha
  • 285
  • 3
  • 5
0

ugh, just to iterate over my own case, which gave out approximately the same error - in the Resource declaration (server.xml) make sure to NOT omit driverClassName, and that e.g. for Oracle it is "oracle.jdbc.OracleDriver", and that the right JAR file (e.g. ojdbc14.jar) exists in %CATALINA_HOME%/lib

hello_earth
  • 1,442
  • 1
  • 25
  • 39