0

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

Rafael Afonso
  • 595
  • 1
  • 10
  • 28

2 Answers2

0

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:

Community
  • 1
  • 1
unwichtich
  • 13,712
  • 4
  • 53
  • 66
  • 1
    I have a similar issue and my project's structure is similar to what you are proposing. How do you tell Maven to include the interfaces (or the jar with the beans) in the `lib/` folder? – Alvaro Pedraza Jun 23 '16 at 16:22
0

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.

Alvaro Pedraza
  • 1,176
  • 6
  • 20
  • 44