Glassfish 3.0: Exception while deploying ejb module...Invalid ejb j ar: it contains zero ejb

1.2k views Asked by At

I have a very simple ejb 3.0 module with maven, it has only two session beans one stateless and the other is singleton...when I am trying to deploy the project on Glassfish 3.0 server, I got this exception:

Error occurred during deployment: Exception while deploying the app : Invalid ejb jar : it contains zero ejb. Note: 1. A valid ejb jar requires at least one session, entity (1.x/2.x style), or message-driven bean. 2. EJB3+ entity beans (@Entity) are POJOs and please package them as library jar. 3. If the jar file contains valid EJBs which are annotated with EJB component level annotations (@Stateless, @Stateful, @MessageDriven, @Singleton), please check server.log to see whether the annotations were processed properly.. Please see server.log for more details.

I verify the project with the Glassfish Verifier Tool, I got this exception, but I don't know what should I do?

Verifier output unparsable
Verifier output (C:\Users\Mariam.Moustafa\Documents\NetBeansProjects\web\EmployeesTimer\target\EmployeesTimer-1.0-SNAPSHOT.jar.xml) not found.

Here is The pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.unilever</groupId>
    <artifactId>EmployeesTimer</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>ejb</packaging>

    <name>EmployeesTimer</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-bundle</artifactId>
            <version>1.8</version>
        </dependency>

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.2</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.2</version>
        </dependency>

        <!-- slf4j Logger -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.7</version>
        </dependency>    

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.7</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ejb-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <ejbVersion>3.1</ejbVersion>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>6.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>unknown-jars-temp-repo</id>
            <name>A temporary repository created by NetBeans for libraries and jars it could not identify. Please replace the dependencies in this repository with correct ones and delete this repository.</name>
            <url>file:${project.basedir}/lib</url>
        </repository>
        <repository>
            <id>m2.dev.java.net</id>
            <url>http://download.java.net/maven/2</url>
            <layout>default</layout>
        </repository>
        <repository>  
            <id>prime-repo</id>  
            <name>PrimeFaces Maven Repository</name>  
            <url>http://repository.primefaces.org</url>  
            <layout>default</layout>  
        </repository>  
    </repositories>
</project>

I confirm that I have 2 simple ejb

@Stateless public class EmployeesFacade {} 
@Singleton public class TimerService { 
@EJB EmployeesFacade emloyeesFacade;
} 

Here is the code:

First @singleton ejb bean

package com.employeestimer.services;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.unilever.employeestimer.enums.ConnectionEnum;
import com.unilever.employeestimer.exceptions.BusinessException;
import java.io.IOException;
import javax.ejb.EJB;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.naming.NamingException;
import javax.ws.rs.core.MediaType;
import org.codehaus.jackson.JsonProcessingException;
import org.slf4j.LoggerFactory;


@Singleton
public class TimerService {
    static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TimerService.class);

    @EJB
    EmployeesFacade  emloyeesFacade;

    private final static String U_ENGAGE_URL = "http://..../webresources/employees/update";

    @Schedule(second="*", minute="*/1",hour="*", persistent=false)
    public void doWork() throws JsonProcessingException, IOException, NamingException{
       try{
            String input = emloyeesFacade.getUsersData(ConnectionEnum.USERNAME.getCode(), ConnectionEnum.PASSWORD.getCode());
            consumeRESTfulWebService(input);            
       }catch(BusinessException e){
           LOGGER.error("",e);
       }

    }

    private void consumeRESTfulWebService(String input){             
       try {
            LOGGER.debug("input = " + input);
            Client client = Client.create();
            WebResource webResource = client.resource(U_ENGAGE_URL);
            ClientResponse response = webResource.type(MediaType.TEXT_PLAIN).post(ClientResponse.class, input);
            if (response.getStatus() != ClientResponse.Status.NO_CONTENT.getStatusCode()) {
                throw new RuntimeException("Failed : HTTP error code : "
                     + response.getStatus());
            }
            LOGGER.debug("Output from Server .... \n");
        } catch (Exception e) {
            LOGGER.error("",e);
    }
    }
}

and here is the Facade bean:

package com.employeestimer.services;

import com.employeestimer.beans.EmployeeData;
import com.employeestimer.enums.ConfigurationsEnum;
import com.employeestimer.enums.ConnectionEnum;
import com.employeestimer.exceptions.BusinessException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import javax.ejb.Stateless;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.PagedResultsControl;
import javax.naming.ldap.PagedResultsResponseControl;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
import org.slf4j.LoggerFactory;


@Stateless
public class EmployeesFacade {

    static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(EmployeesFacade.class);

    public String getLDAPConnectionType() {
        return ConfigurationsEnum.LDAP_Connection_Type.getCode();
    }

    public String getDomain() {
        return ConfigurationsEnum.DOMAIN.getCode();
    }

    public String getLDAPIP() {
        return ConfigurationsEnum.LDAP_IP.getCode();
    }

    public String getLDAPPort() {
        return ConfigurationsEnum.LDAP_PORT.getCode();
    }

    public String getLDAPBase() {
        return ConfigurationsEnum.LDAP_BASE.getCode();
    }

    private LdapContext getContext(String username, String password) throws BusinessException, NamingException {
        Hashtable env = new Hashtable();
        if (getDomain() == null || getLDAPConnectionType() == null
                || getLDAPIP() == null || getLDAPPort() == null) {
            throw new BusinessException("error_general");
        }
        String domain = getDomain();
        String url = getLDAPConnectionType() + "://" + getLDAPIP() + ":" + getLDAPPort();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, url);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.REFERRAL, "follow");
        if (!username.contains("@")) {
            username = username + "@" + domain;
        }
        env.put(Context.SECURITY_PRINCIPAL, username);
        env.put(Context.SECURITY_CREDENTIALS, password);
        return new InitialLdapContext(env, null);
    }

    public String getUsersData(String username, String password) throws BusinessException, JsonProcessingException, IOException, NamingException {
        List<EmployeeData> employeelist = new ArrayList<EmployeeData>();
        EmployeeData employee;
        String json = "";
        try {
            LdapContext context = getContext(username, password);
            SearchControls constraints = new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
            String[] attrIDs = {"mail"};    //, "sn", "cn", "c", "l"};
            constraints.setReturningAttributes(attrIDs);
            // Activate paged results
            int pageSize = Integer.parseInt(ConnectionEnum.PAGESIZE.getCode());
            byte[] cookie = null;
            context.setRequestControls(new Control[]{new PagedResultsControl(pageSize,
                Control.NONCRITICAL)});
            int total;
            NamingEnumeration<SearchResult> result = null;
            do {
                /* perform the search */
                result = context.search(getLDAPBase(), "(&(objectClass=User)(c=EG))", constraints);
                /* for each entry print out name + all attrs and values */
                while (result != null && result.hasMore()) {
                    SearchResult entry = (SearchResult) result.next();
                    employee = new EmployeeData();
                    Attribute attribute;

                    if (entry.getAttributes() != null) {
                        if (entry.getAttributes().get("mail") != null) {
                            attribute = entry.getAttributes().get("mail");
                            employee.setEmail(attribute != null ? attribute.toString().replace("mail: ", "") : "");
                            employeelist.add(employee);
                        }
                    }
            }
                // Examine the paged results control response
                Control[] controls = context.getResponseControls();
                if (controls != null) {
                    for (int i = 0; i < controls.length; i++) {
                        if (controls[i] instanceof PagedResultsResponseControl) {
                            PagedResultsResponseControl prrc = (PagedResultsResponseControl) controls[i];
                            total = prrc.getResultSize();
                            if (total != 0) {
                                LOGGER.debug("***************** END-OF-PAGE " + "(total : " + total + ") *****************\n");
                            } else {
                                LOGGER.debug("***************** END-OF-PAGE " + "(Page no. " + i + ") ***************\n");
                            }
                            cookie = prrc.getCookie();
                        }
                    }
                } else {
                    LOGGER.debug("No controls were sent from the server");
                }
                // Re-activate paged results
                context.setRequestControls(new Control[]{new PagedResultsControl(
                    pageSize, cookie, Control.CRITICAL)});
            } while (cookie != null);
            //result.close();
            context.close();
            ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
            json = ow.writeValueAsString(employeelist);
            LOGGER.debug("\n \n \n ************* \n ************* \n ************* \n \n THE SIZE = " + employeelist.size() + "\n \n ************* \n ************* \n ************* \n \n \n");
        } catch (NamingException ex) {
            String detailmessage = ex.getExplanation();
            if (detailmessage.contains(" 32 ")) {
                // User not Found
                throw new BusinessException("error_invalidUser");
            } else if (detailmessage.contains(" 49 ")) {
                if (detailmessage.contains(" 775 ") || detailmessage.contains(" 701 ") || detailmessage.contains(" 533 ")) {
                    //Invalid Account
                    throw new BusinessException("error_invalidAccount");
                } else {
                    //Invalid Username or password
                    throw new BusinessException("error_invalidUsernamePassword");
                }
            } else {
                LOGGER.error("error_general", ex);
                throw new BusinessException("error_general");
            }
        }
        return json;
    }
}
1

There are 1 answers

6
unwichtich On

I don't see a problem with your setup. If you really have some class annotated with @Singleton or @Stateless inside this project, this should work.

But one important point is that if you have any dependencies which are not available in the libs of Glassfish, you have to package them with your application which is not possible with EJB/JAR packaging. You have to package it as a WAR or EAR file.

For a quick start, try the following:

Change

<packaging>ejb</packaging>

to

<packaging>war</packaging>

and change

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ejb-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <ejbVersion>3.1</ejbVersion>
            </configuration>
        </plugin>

to

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>

If you want to package it as an EAR, you can use the maven-ear-plugin.

See also: