How to configure Gradle to built Java EE project - eclipse

I try to setup a Java EE environment to be built with gradle. In the end I want to have an EAR file containing an EJB-Jar and some kind of application client that can be deployed to Glassfish (probably). The setup will be quite basic.
Currently I am facing two problems:
1) Running the 'ear' task to assemble the EAR archive creates a faulty application.xml file in tmp/ear that looks like this:
<?xml version="1.0"?>
<application xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="6">
<display-name>DataViewerEAR</display-name>
<library-directory>lib</library-directory>
</application>
The error message eclipse reports is:
cvc-complex-type.2.4.a: Invalid content was found starting with
element 'library-directory'. One of
'{"http://java.sun.com/xml/ns/javaee":display-name,
"http://java.sun.com/xml/ns/javaee":icon,
"http://java.sun.com/xml/ns/javaee":initialize-in-order,
"http://java.sun.com/xml/ns/javaee":module}' is expected.
The deployment descriptor file I created with the help of eclipse in earContent/META-INF seems to be ignored:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/application_7.xsd" version="7">
<display-name>DataViewerEAR</display-name>
<module>
<ejb>DataViewerEJB.jar</ejb>
</module>
<module>
<java>DataViewerTestClient.jar</java>
</module>
</application>
The content of the asssembled EAR file looks ok.
2) The resulting jar of the EJB build is empty. I think the main problem is that the EJB project's structure does not match the assumed src/main/java etc. and I don't know how to change this. My current build.gradle file for the EJB project looks like this:
apply plugin: 'java'
repositories {
jcenter()
}
dependencies {
compile 'ch.qos.logback:logback-classic:1.1.5'
testCompile 'junit:junit:4.12'
}
It would also be great If someone could tell me what things you have to pay attention to when configuring the application. Deployment descriptors and other .xml files. Not to forget anything...

As far as I found out the easiest way to make gradle find the classes is to modify the sourceSets. In my case adding
sourceSets {
main {
java {
srcDir 'ejbModule'
}
}
test {
java {
srcDir 'test'
}
}
}
to the EJB build file and
appDirName "EarContent"
to the EAR build file seems to be sufficient in my case although I wasn't able to test it because there are other problems left.

Related

JBoss EAR deployment fails because WAR classes are unable to find jars from EAR/lib folder

I am using JBoss EAP 7 and want to deploy an EAR file in standalone mode (using standalone-ha.xml).
I went through almost everything available on StackOverflow/JBoss forums but couldn't make my deployment to work (correctly). I have followed the docs to the best of my abilities but still the deployment of EAR gives Exception on console because the jar files inside WAR/WEB-INF/lib are not able to see the jar files present int EAR/lib folder. I can't figure out what I am doing wrong.
Structure
myEAR.ear
|- lib (contains a.jar)
|- META-INF
|--- maven (folder with pom)
|--- application.xml
|--- jboss-deployment-structure.xml
|--- MANIFEST.MF
|- myWar.war
|--- WEB-INF
|----- lib (contains b.jar)
|----- jboss-deployment-structure.xml (which should be ignored per the docs)
|----- (WEB-INF contains other files/folders such as classes,jsp etc
EAR- application.xml:
<?xml version="1.0" encoding="UTF-8"?>
<application 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/application_7.xsd" version="7">
<display-name>myear</display-name>
<module>
<web>
<web-uri>myWAR.war</web-uri>
<context-root>/mywar</context-root>
</web>
</module>
<library-directory>lib</library-directory>
</application>
EAR- jboss-deployment-structure.xml:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<deployment>
<dependencies>
<module name="com.organization.global" export="true" />
</dependencies>
</deployment>
<!-- Having/Not having below sub-deployment has no effect -->
<sub-deployment name="myWAR.war">
<dependencies/>
</sub-deployment>
</jboss-deployment-structure>
Deployment succeeds if I copy a.jar inside WAR/WEB-INF/lib/ folder, otherwise gives an exception: Caused by: java.lang.NoClassDefFoundError related to a class specific to a.jar. I want my WAR to be able to get access to all the jars put together inside EAR/lib.
I read in one of the forums that the jar/classes in lib folder should be available to all modules within the EAR but sometimes they are not added automatically but I couldn't find the solution on how to add them.
Any guidance would be appreciated. Thanks in advance!
In JBoss EAP 7, to access lib files present in ear inside war you could try by adding a context param in your war's web.xml.
To create env variable try below in terminal:
export JAR_HOME=../jboss-eap-7.1/standalone/deployments/example.ear(Please add value equivalent to your environment and ear's path)
export PATH=$PATH:$JAR_HOME
Add this variable to web.xml as file:${JAR_HOME}/lib/example.jar
Read this context param inside your classes present inside war.

Precedence of EJB Deployment Descriptors

If I have an EJB packaged in a WAR because it is exposed as a REST web service, according to this link, I need to have the ejb-*.xml files at the root of the WEB-INF directory. My current environment is Websphere 8.5 and EJB 3.1
If I later add multiple EJBs ( in separate EJB projects ) in the same application and define its deployment descriptors in the respective projects, those seem to be ignored. It appears that ALL of my descriptors should be defined in the descriptors in the WEB-INF directory - or in other words, it seems that I should augment the descriptors in WEB-INF directory even for EJBs that are defined as separate projects.
Is this how it needs to be or am I missing something that is forcing me to do this? I could not find any documentation explaining this part.
More Details:
This is how my application.xml looks like
<?xml version="1.0" encoding="UTF-8"?>
<application 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/application_7.xsd"
version="7">
<display-name>MyApp</display-name>
<module id="Module_1395346343165">
<web>
<web-uri>MyWeb.war</web-uri>
<context-root>myapp</context-root>
</web>
</module>
<module id="Module_1395346304194">
<ejb>ejb1.jar</ejb>
</module>
<module id="Module_1424684968934">
<ejb>ejb2.jar</ejb>
</module>
<module id="Module_1431010943758">
<ejb>ejb3.jar</ejb>
</module>
</application>
The ejb1 is the one that will live in the webapp. The other two, ejb2 and ejb3 are separate ejb projects that are supposed to be in EAR's root.
For EJBs in a WAR module, the files go in WEB-INF, so .ear!/MyWeb.war!/ejb-jar.xml, .ear!/MyWeb.war!/ibm-ejb-jar-bnd.xml, etc.
For EJBs in separator EJB modules outside a WAR, the files go in META-INF. So, .ear!/ejb1.jar!/META-INF/ejb-jar.xml, .ear!/ejb1.jar!/META-INF/ibm-ejb-jar-bnd.xml, etc.

Glassfish v3: Web application not finding JAR in the same EAR

I created a EAR application in Eclipse to run in Glassfish 3.1. The used projects are: BibliotecaEAR2 (the main EAR. 'Biblioteca' means 'Library'), BibliotecaEJB (with EJBs), BibliotecaModel (with entities and DAOs) and BibliotecaWeb (The Web application). The application.xml has this structure:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" id="Application_ID" version="6">
<display-name>BibliotecaEAR2</display-name>
<module>
<web>
<web-uri>BibliotecaWeb.war</web-uri>
<context-root>biblioteca</context-root>
</web>
</module>
<module>
<ejb>BibliotecaEJB.jar</ejb>
</module>
</application>
In BibliotecaWeb, the META-INF/MANIFEST.MF is written this:
Manifest-Version: 1.0
Class-Path: lib/google/guava-18.0.jar
// other JARs in BibliotecaEAR2 project
BibliotecaEJB.jar
When I start the glassfish I get this warning message:
2014-10-20T14:34:31.691-0200|WARNING: PWC6351: In TLD scanning, the supplied resource file:/C:/dev/glassfish3/glassfish/domains/biblioteca-glass3/eclipseApps/BibliotecaEAR2/BibliotecaEJB.jar does not exist
java.io.FileNotFoundException: C:\dev\glassfish3\glassfish\domains\biblioteca-glass3\eclipseApps\BibliotecaEAR2\BibliotecaEJB.jar (O sistema nao pode encontrar o arquivo especificado)
Although it does not stop me from running the application, I would like to eliminate it.
Googling for PWC6351 warning, I perceived that it happens when a used JAR is not found in the Manifest File. However the request JAR is not simply a external library, but a sub-project in same EAR. Is there any additional configuration that should I do?
Thanks,
Rafael Afonso
From Packaging libraries with EARs:
When packaging applications in an EAR file, the library JARs need to
be placed in the archive lib directory (jars at the archive root level
are not added to the classpath and thus available from other EAR
artifacts.)
The library jars placed in the "/lib" directory of the EAR (the
directory name can be overridden in application.xml) will be visible
to all sub-modules (JARs, WARs, and RARs) with no further
configuration. No need to add Class-Path entries in the EAR manifest.
In fact you don't need to reference the jars in the lib folder, and it looks like it will not work if you reference a jar on the EAR root level, like your BibliotecaEJB.jar.
If you don't have a real dependency from your WAR module classes to your EJB module classes you can just remove all the entries from the MANIFEST.MF and it should work.
If you instead have a real dependency from WAR to EJB, you may have to think about your project structure and if you really need an EAR. You can also package all the stuff into a single WAR.
The right way to use an EAR with WAR and EJB modules requires a little bit of work if your current WAR classes directly depend on classes from the EJB module:
1. Step
You have to create interfaces for all your "service" classes which should be available to classes in the web application (WAR).
Here is a simple example:
public interface FileService {
public void showFileInformation(File file);
}
and
#Stateless
#Local(FileService.class)
#Remote(FileService.class)
public class FileServiceImpl implements FileService {
#Override
public void showFileInformation(File file) {
// here
// is
// the
// real
// stuff
}
}
2. Step
The next step is to package all your new interfaces into a new jar. Your model jar looks similar to this approach. If this can't be used for this purpose, create a simple java application project which gets packaged as jar and put all the interfaces into this project. This jar has to be in the lib folder of the EAR.
BibliotecaEAR2
-- BibliotecaEJB
-- BibliotecaWeb
-- /lib/interfaces.jar
Then you have to add a dependency to this new jar in your WAR and EJB modules, so that they can find the interface classes.
3. Step
The services can be injected into the managed classes of your web applications (and into other service classes) like this:
#RequestScoped
public class FileHandler {
// make sure to use the interface
#EJB
FileService fileService;
}
Maybe you already have something similar to this, but then it should work without any entries in the MANIFEST.MF.
See also:
Maven2: Best practice for Enterprise Project (EAR file)
Java EE - EAR vs separate EJB+WAR
Packaging EJB in JavaEE 6 WAR vs EAR
I had a similar issue and solved by customizing module location, like this
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" id="Application_ID" version="6">
<display-name>BibliotecaEAR2</display-name>
<module>
<web>
<web-uri>BibliotecaWeb.war</web-uri>
<context-root>biblioteca</context-root>
</web>
</module>
<module>
<ejb>BibliotecaEJB.jar</ejb>
<bundleDir>/lib</bundleDir> <!-- ADD THIS OPTION TO THE MODULE -->
</module>
</application>
This solution is taken from the Maven EAR plugin documentation, which uses Maven 3 syntax, but I think you can use it too (or you can migrate to Maven 3).
Hope that helps.

Problems with eclipse and maven war plugin overlay

I have a project where I am replacing out the web.xml and other files using a war overlay in maven. Everything works great and then I try to import into eclipse and have all kinds of problems.
To start with I use mvn eclipse:eclipse to generate my Eclipse files. This works but the imported project does not contain the Dynamic Web facet.
Once the Dynamic Web facet (version 2.5) is added, the project still recognizes the deployment descriptor as 2.4 and gives me errors anyway even though it is;
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<web-app version="2.5" 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_5.xsd">
Has anyone struggled through this type of thing before?

How to define a custom EAR file name for a specific application?

Here is my setup
SDK: Eclipse Ganymede (3.4.2)
App Server: jBoss 4.2.3GA
I got three projects:
MYAPP, which is the main project, with only libraries and log4j configurations. This is where application.xml and jboss-app.xml resides.
MYAPPEJB, which is my business logic project in which I have my entity beans, sessions beans.
MYAPPWeb, which is my client logic project in which I have my Struts Forms, Struts Actions, JSPs and Jasperreports reports.
When I publish my project to my jBoss server on my laptop, I got the following EAR file name: MYAPP.ear, which make sense.
I would like to define a different custom name for the final EAR, let's say ACCOUNTMANAGER.ear
Here is my application.xml file
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" id="Application_ID" version="5">
<display-name>MYAPP</display-name>
<module>
<ejb>MYAPPEJB.jar</ejb>
</module>
<module>
<web>
<web-uri>MYAPPWeb.war</web-uri>
<context-root>/manager/myapp</context-root>
</web>
</module>
<library-directory>/lib</library-directory>
</application>
Any idea?
Thank you
Charles
You can specify your ear file name in application.xml file under web -> web-uri tag. Please check this link for your reference. web-uri
You can specify in application.xml file. It will pick up this name instead of ear file name.
MyEarName