I'm new to JavaEE and I created a "hello world" project, using Hibernate as JPA provider, build using gradle and deployed to Wildfly. I want to use @Stateless
bean for database-aware class, that will do all operations on DB, and then inject it to all "JAX-RS" classes, that contain REST endpoints.
Database class:
@Stateless
public class DatabaseManager {
@PersistenceContext
EntityManager entityManager;
public DatabaseManager() {
}
public String sayHello() {
// do some db-stuff
return "EHLO";
}
}
REST class:
@Path("/")
@SessionScoped
public class RestMainEndpoint implements Serializable {
@EJB
private DatabaseManager databaseManager;
public RestMainEndpoint() {
}
@GET
@Path("/hello")
@Produces("text/plain")
public String helloFromDb() {
return databaseManager.sayHello();
}
}
Problem is that @EJB private DatabaseManager databaseManager;
is always null
. It never gets injected.
I know that the REST is working, since all non-db related endpoints are working fine. I also assume that DatabaseManager
bean is created and initialized, since I can see it on Wildfly admin panel.
I'm not sure if I'm packaging and deploying it right - it's all packed to single war
and deployed. Is it necessary for me to use ear
or create separate project? I tried, but I was unable to successfully convert it to ear
project with gradle.
edit: in WEB-INF
directory of my source files I won't have any jars, only web.xml and recently added beans.xml
(which doesn't seem to have any effect). Is it necessary?
web.xml
content:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Desktopeo</display-name>
<servlet>
<servlet-name>desktopeo</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>
jersey.config.server.provider.packages
</param-name>
<param-value>
edu.desktopeo.server
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>desktopeo</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
beans.xml
content:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all">
</beans>
However, in output war
archive (which is really a zip archive), I have a lot of jars:
My project jars: Commons-1.0.jar
(few POJO classes)
My lib jars: (libs I added by myself using gradle)
commons-codec-1.10.jar
commons-collections4-4.0.jar
commons-io-2.4.jar
commons-lang3-3.4.jar
guava-19.0-rc2.jar
My Database-related jars:
hibernate-commons-annotations-5.0.0.Final.jar
hibernate-core-5.0.2.Final.jar
hibernate-entitymanager-5.0.2.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
sqljdbc4.jar // JDBC driver for MS SQL
Other jars: (probably mostly other dependencies)
javaee-api-7.0.jar
activation-1.1.jar
antlr-2.7.7.jar
aopalliance-repackaged-2.4.0-b31.jar
dom4j-1.6.1.jar
genson-1.3.jar
geronimo-jta_1.1_spec-1.1.1.jar
hk2-api-2.4.0-b31.jar
hk2-locator-2.4.0-b31.jar
hk2-utils-2.4.0-b31.jar
jandex-1.2.2.Final.jar
javassist-3.18.1-GA.jar
javax.annotation-api-1.2.jar
javax.inject-1.jar
javax.inject-2.4.0-b31.jar
javax.mail-1.5.0.jar
javax.ws.rs-api-2.0.1.jar
jboss-logging-3.3.0.Final.jar
jersey-client-2.22.1.jar
jersey-common-2.22.1.jar
jersey-container-servlet-2.22.1.jar
jersey-container-servlet-core-2.22.1.jar
jersey-guava-2.22.1.jar
jersey-media-jaxb-2.22.1.jar
jersey-server-2.22.1.jar
jsoup-1.8.3.jar
log4j-1.2.17.jar
slf4j-api-1.7.2.jar
slf4j-log4j12-1.7.2.jar
osgi-resource-locator-1.0.1.jar
validation-api-1.1.0.Final.jar
xml-apis-1.0.b2.jar
PROBLEM SOLVED
As Steve C wrote in the answer, the problem was related to unnecessary jar
s in output war
. I changed scope of few of them to provided
and it helped (and also made war
4 times smaller).
Server side gradle build, for future reference:
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'idea'
repositories {
mavenCentral()
}
buildscript {
repositories {
jcenter()
}
}
configurations {
provided
}
sourceSets {
main.compileClasspath += configurations.provided
test.compileClasspath += configurations.provided
test.runtimeClasspath += configurations.provided
}
idea {
module {
scopes.PROVIDED.plus += [configurations.provided]
}
}
dependencies {
provided 'javax:javaee-api:7.0'
provided 'org.hibernate:hibernate-core:5.0.2.Final'
provided 'org.hibernate:hibernate-entitymanager:5.0.2.Final'
// other libs, with regular "compile"
}
Your EJB is not being injected because you have packaged your own copy of a JAX-RS implementation into your web app. This implementation does not know how to inject EJBs.
As this is WildFly 9, you can get rid of all the jersey jars, their dependencies and the complete web.xml.
In your gradle file you need to ensure that the javaee-api-7.0 dependency is given a scope of
provided
. It should not be packaged with your application as the server provides these classes. You also need to completely remove gradle references to:because these classes are all provided by the javaee-api-7.0 dependency.
Finally, add a java source file containing:
which provides the configuration removed with the web.xml and you should be good to go.