Search code examples
jboss7.xjava-ee-6cdi

NPE with @Inject in WAR from a JPA utility jar


env: JBoss 7.1.1, jdk 1.7, WELD module upgraded to 1.1.10(just in case)

I have a JPA project that I am adding to the WEB-INF\lib directory. It contains my entities and DAO objects, which has the Entity Manager inject. I'm using custom annotations to qualify the PersistenceContext, which is Produced in a Resources class. I've run Arquillian tests in this project to ensure it works.

I have a beans.xml file in the \META-INF\ directory of the JPA jar and in the \WEB-INF\ directory of the war file. I even printed it out and put it on my desk, still didn't help.

Within my war file I have a class that is injecting a DAO object from the JPA jar. Its not working, its null.

I've found examples from the jboss (without jpa jar) with CDI and it works.

I've looked for examples but cannot find any with a jpa jar. Can anyone point me to where there is an example of a jee6 web app, with a JPA utility jar, that uses annotations to inject something from the JPA jar into the war classes?

Thank you very much for reading this plea.

--------------------additional info-----------------

structure of war file

META-INF
->maven
-->com.xyz
--->web
---->pom.properties
---->pom.xml
->MANIFEST.MF
WEB-INF
->classes
->lib
-->entities.jar
->beans.xml
->faces-config.xml
->web.xml

stack trace: 22:23:12,011 INFO [org.quartz.core.JobRunShell] (DefaultQuartzScheduler_Worker-2) Job DEFAULT.extractDir threw a JobExecutionException: : org.quartz.JobExecutionException: java.lang.NullPointerException [See nested exception: java.lang.NullPointerException] at com.xyz.asp.commsrv.scheduler.jobs.DirScanJob.execute(DirScanJob.java:149) [classes:] at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [quartz-2.1.7.jar:] at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) [quartz-2.1.7.jar:] Caused by: java.lang.NullPointerException at com.xyz.asp.commsrv.scheduler.jobs.DirScanJob.execute(DirScanJob.java:140) [classes:] ... 2 more

This is the class that has the DAO object injected. This is a quartz scheduler job which is started by a ServletContextListener during jboss startup:

@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class DirScanJob implements Job{
    ...
    @Inject
    FiletracksentHome ftsHome;


    @Override
    public void execute(JobExecutionContext context) throw JobExecutionException{
        ...
        BigDecimal bd = ftsHome.nextId()
    }
}

This class resides in entities.jar:

@Stateless
public class FiletracksentHome{

    @Inject
    @DatabaseEntities
    private EntityManager entityManager;

    public BigDecimal nextId(){
    ...
    }
}

Solution

  • CDI is available in the ServletContextListener but nothing within the context of the Quartz Scheduler. I didn't want to bother with another library, since CDI wasn't necessary. I injected some properties that I needed using the @Resource annotation within the ServletContextListener implementation ...

    @Resource(lookup = "java:app/env/quartzjobdirectory")
    private String quartzJobDirectory;
    

    and within the web.xml ...

    <env-entry>
       <description>Quartz Jobs Directory</description>
       <env-entry-name>java:app/env/quartzjobdirectory</env-entry-name>
       <env-entry-type>java.lang.String</env-entry-type>
       <env-entry-value>/appl/jboss-as-7.1.1.Final/standalone/configuration/quartz_jobs/</env-entry-value>
    </env-entry>
    

    And for the EJB calls within the Quartz Jobs because DI is not available I did some JNDI calls, such as ...

    InitialContext ic = new InitialContext();
    readyDocs = (ReadyDocumentsLocal) ic.lookup("java:global/commsrv-ear-1.0.0/commsrv-ejb-1.0.0/ReadyDocumentsBean!com.ista.asp.commsrv.ReadyDocumentsLocal");
    

    and the EJB ...

    @Stateless
    public class ReadyDocumentsBean implements ReadyDocumentsLocal {
       ...
    }
    

    FYI ... jboss as 7.1 will output to the server.log the JNDI bindings for session beans.