Search code examples
jpajakarta-eenetbeansglassfishejb

How to solve Java EE EJB Glassfish error javax.naming.NamingException: Invocation exception: Got null ComponentInvocation?


I have a problem with creating a simple databse with EJB. I created a Web Project in Netbeans with Maven. I am using Glassfish 5 however the problem also occurs with glassfish 4.

Here are my classes.

Ui_model.java:

@Named("model")
@Stateless
public class Ui_model implements Serializable{

    @Inject 
    PizzaRepository pizzas;

    public Ui_model() {
    }

    @PostConstruct
    public void init(){

        Pizza one = new Pizza(1, "Pizza Margaritta", 4.5);
        Pizza two = new Pizza(2, "Pizza Napoli", 5);
        Pizza three = new Pizza(3, "Pizza Calzone", 6);

        pizzas.createDB(one);
        pizzas.createDB(two);
        pizzas.createDB(three);  
    }
}

PizzaRepository.java:

@Named
@ApplicationScoped
public class PizzaRepository implements Serializable{
    @PersistenceContext(unitName="Unit")
    protected EntityManager em;

    public void createDB(Pizza pizza){
        try{
            em.persist(pizza);
        }catch(RollbackException e){
            System.out.println(e.getMessage());
        }

    }
}

Pizza.java:

@Entity
public class Pizza implements Serializable{
    @Id
    int number;
    String name;
    double price;

    public Pizza(int number, String name, double price) {
        this.number = number;
        this.name = name;
        this.price = price;
    }
    public Pizza(){

    }
}

This is my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="Unit" transaction-type="JTA">
        <jta-data-source>java:app/jdbc/testdb</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <!-- database connection -->
            <property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
        </properties>
    </persistence-unit>
</persistence>

This is my glassfish-resources.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
    <jdbc-connection-pool allow-non-component-callers="false" 
                          associate-with-thread="false" 
                          connection-creation-retry-attempts="0" 
                          connection-creation-retry-interval-in-seconds="10" 
                          connection-leak-reclaim="false" 
                          connection-leak-timeout-in-seconds="0" 
                          connection-validation-method="auto-commit" 
                          datasource-classname="org.apache.derby.jdbc.ClientDataSource" 
                          fail-all-connections="false" idle-timeout-in-seconds="300" 
                          is-connection-validation-required="false" 
                          is-isolation-level-guaranteed="true" 
                          lazy-connection-association="false" 
                          lazy-connection-enlistment="false" 
                          match-connections="false" 
                          max-connection-usage-count="0" 
                          max-pool-size="32" 
                          max-wait-time-in-millis="60000" 
                          name="derby_net_testdb_usernamePool" 
                          non-transactional-connections="false" 
                          pool-resize-quantity="2" 
                          res-type="javax.sql.DataSource" 
                          statement-timeout-in-seconds="-1" 
                          steady-pool-size="8" 
                          validate-atmost-once-period-in-seconds="0" 
                          wrap-jdbc-objects="false">
        <property name="serverName" value="localhost"/>
        <property name="portNumber" value="1527"/>
        <property name="databaseName" value="testdb"/>
        <property name="User" value="username"/>
        <property name="Password" value="123456"/>
        <property name="URL" value="jdbc:derby://localhost:1527/testdb"/>
        <property name="driverClass" value="org.apache.derby.jdbc.ClientDriver"/>
    </jdbc-connection-pool>
    <jdbc-resource enabled="true" 
                   jndi-name="java:app/jdbc/testdb" 
                   object-type="user" 
                   pool-name="java:app/derby_net_testdb_usernamePool"/>
</resources>

My project structure: My project structure:

When I run this I get the following error:

enter image description here

The strange thing is that this still creates an empty table named Pizza in the testdb but with no entries. So it doesn't mean that the program is not finding the DB itself. I really don't know what to make of that error. The project was much bigger originally but I broke it down to get to the base problem and it doesn't get much easier than this. Still it doesn't work. I would appreciate any advice on how to fix it.

Edit: asadmin list-jndi-entries prompts:

java:global: com.sun.enterprise.naming.impl.TransientContext
UserTransaction: com.sun.enterprise.transaction.startup.TransactionLifecycleService$2
__internal_java_app_for_app_client__testdb__java:app: com.sun.enterprise.naming.impl.TransientContext
concurrent: com.sun.enterprise.naming.impl.TransientContext
com.sun.enterprise.container.common.spi.util.InjectionManager: com.sun.enterprise.container.common.impl.util.InjectionManagerImpl
jms: com.sun.enterprise.naming.impl.TransientContext
ejb: com.sun.enterprise.naming.impl.TransientContext
jdbc: com.sun.enterprise.naming.impl.TransientContext
Command list-jndi-entries executed successfully.

asadmin list-jndi-entries --context jdbc prompts:

__default: org.glassfish.resourcebase.resources.api.ResourceProxy
__TimerPool: org.glassfish.resourcebase.resources.api.ResourceProxy
sample: org.glassfish.resourcebase.resources.api.ResourceProxy
Command list-jndi-entries executed successfully.

Solution

  • I was able to solve the problem by putting the glassfish.xml into an setup file in src. I also got help from a friend who gave me his files.

    glassfish.xml:

        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
        <resources>
            <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="org.apache.derby.jdbc.ClientDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="derby_net_testdb_pizzaPool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
                <property name="serverName" value="localhost"/>
                <property name="portNumber" value="1527"/>
                <property name="databaseName" value="testdb"/>
                <property name="User" value="username"/>
                <property name="Password" value="123456"/>
                <property name="connectionAttributes" value=";create=true" />
                <property name="URL" value="jdbc:derby://localhost:1527/testdb;create=true"/>
                <property name="driverClass" value="org.apache.derby.jdbc.ClientDriver"/>
            </jdbc-connection-pool>
            <jdbc-resource enabled="true" jndi-name="jdbc/testdb" object-type="user" pool-name="derby_net_testdb_pizzaPool"/>
        </resources>
    
    persistence.xml:
    
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
      <persistence-unit name="Unit" transaction-type="JTA">
        <jta-data-source>jdbc/testdb</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
          <!--<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/ModulDB"/>
            <property name="javax.persistence.jdbc.user" value="pizza"/>
            <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
            <property name="javax.persistence.jdbc.password" value="123456"/>-->
          <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
        </properties>
      </persistence-unit>
    </persistence>
    

    However I then got an error Could not create stateless EJB because of the persist call. That I could resolve by not calling createDB() in the PostConstruct init(). I don't know why but it just didn't work with post construct. Now everything works properly so far. Thank you all very much.