Kohei Nozaki's blog 

Entries tagged [ejb]

Arquillian EJB-JAR/EAR testing examples


Posted on Friday Mar 20, 2015 at 10:33AM in Arquillian


There are plenty of examples of Arquillian testing with WAR deployments, but not for other deployments such as EJB-JAR or EAR. so I created some examples. these examples were tested against Arquillian 1.1.7.Final, using WildFly 8.2.0.Final as remote container. the entire project can be obtained from GitHub.

Testing against EJB-JAR deployment

Assume we have a simple EJB in a EJB-JAR project as follows:

@Stateless
@LocalBean
public class SomeEjb {
    public String hello(String name) {
        return "Hello, " + name;
    }
}

Test class:

@RunWith(Arquillian.class)
public class EjbJarIT {
    @Deployment
    public static Archive<?> createDeploymentPackage() {
        final Archive archive = ShrinkWrap.create(JavaArchive.class).addClass(SomeEjb.class);
        return archive;
    }

    @EJB
    private SomeEjb someEjb;

    @Test
    public void test() {
        Assert.assertEquals("Hello, Kyle", someEjb.hello("Kyle"));
    }
}

The deployment will be a WAR through Arquillian’s automatic enrichment process while the method annotated as @Deployment produced JavaArchive.

Testing against EAR deployment

Assume we have a simple EAR project which depends on the preceding EJB-JAR project.

Test class:

@RunWith(Arquillian.class)
public class EarIT {

    @Deployment
    public static Archive<?> createDeploymentPackage() throws IOException {
        final JavaArchive ejbJar = ShrinkWrap.create(JavaArchive.class, "ejb-jar.jar").addClass(SomeEjb.class);

        // Embedding war package which contains the test class is needed
        // So that Arquillian can invoke test class through its servlet test runner
        final WebArchive testWar = ShrinkWrap.create(WebArchive.class, "test.war").addClass(EarIT.class);
        final EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class)
                .setApplicationXML("test-application.xml")
                .addAsModule(ejbJar)
                .addAsModule(testWar);
        return ear;
    }

    @EJB
    private SomeEjb someEjb;

    @Test
    public void test() {
        Assert.assertEquals("Hello, Kyle", someEjb.hello("Kyle"));
    }
}

test-application.xml which will be embed as application.xml:

<application>
    <display-name>ear</display-name>
    <module>
        <ejb>ejb-jar.jar</ejb>
    </module>
    <module>
        <web>
            <web-uri>test.war</web-uri>
            <context-root>/test</context-root>
        </web>
    </module>
</application>

Also I have an another example that uses the EAR which Maven has produced because creating EAR with ShrinkWrap would be annoying in some complex cases. the @Deployment method will embed the test WAR into the EAR, and add a module element into existing application.xml before returning the archive to Arquillian runtime. the @Deployment method would be something like this:

...
@Deployment
public static Archive<?> createDeploymentPackage() throws IOException {
    final String testWarName = "test.war";

    final EnterpriseArchive ear = ShrinkWrap.createFromZipFile(
            EnterpriseArchive.class, new File("target/ear-1.0-SNAPSHOT.ear"));

    addTestWar(ear, EarFromZipFileIT.class, testWarName);
...


An example of Maven EAR project consists of an EJB interface, an EJB implementation and a WAR


Posted on Friday Mar 06, 2015 at 10:43PM in Maven


The project consists of following principal modules:

  • eartest-ejb-api: holds an EJB local interface named Hello. packaging=jar. no dependency.

  • eartest-ejb-impl: holds an EJB implementation named HelloImpl which implements Hello. packaging=ejb. depends on eartest-ejb-api.

  • eartest-war: holds an Servlet which has an injection point of Hello interface. depends on eartest-ejb-api.

  • eartest-ear: holds above 3 modules in the EAR.

Whole project is can be obtained from https://github.com/lbtc-xxx/eartest .

Structure of eartest-ear module

$ tree eartest-ear/target/eartest-ear
eartest-ear/target/eartest-ear
|-- META-INF
|   `-- application.xml
|-- eartest-ejb-impl-1.0-SNAPSHOT.jar
|-- eartest-war-1.0-SNAPSHOT.war
`-- lib
    `-- eartest-ejb-api-1.0-SNAPSHOT.jar

2 directories, 4 files

Structure of eartest-war module

$ tree eartest-war/target/eartest-war
eartest-war/target/eartest-war
|-- META-INF
`-- WEB-INF
    `-- classes
        `-- eartest
            `-- war
                `-- MyServlet.class

5 directories, 1 file

MyServlet can reference eartest-ejb-api-1.0-SNAPSHOT.jar because it’s placed under lib directory in the parent EAR. this packaging style is called as Skinny WAR.

Structure of eartest-ejb-api

$ tree eartest-ejb-api/target/classes
eartest-ejb-api/target/classes
`-- eartest
    `-- ejb
        `-- api
            `-- Hello.class

3 directories, 1 file

Structure of eartest-ejb-impl

$ tree eartest-ejb-impl/target/classes
eartest-ejb-impl/target/classes
|-- META-INF
|   `-- ejb-jar.xml
`-- eartest
    `-- ejb
        `-- impl
            `-- HelloImpl.class

4 directories, 2 files

A problem with IntelliJ IDEA

IntelliJ has an annoying issue: Maven support cannot handle skinny wars for EAR deployments : IDEA-97324. this brings unnecessary eartest-ejb-api into WEB-INF/lib inside the WAR and brings following exception. to avoid this, I need to put <scope>provided</scope> in dependency declaration for eartest-ejb-api in pom.xml of eartest-war.

Caused by: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance
	at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:162)
	at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:133)
	at org.jboss.as.ee.component.BasicComponent.createInstance(BasicComponent.java:89)
	at org.jboss.as.ee.component.ComponentRegistry$ComponentManagedReferenceFactory.getReference(ComponentRegistry.java:149)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$5.createInstance(UndertowDeploymentInfoService.java:1233)
	at io.undertow.servlet.core.ManagedServlet$DefaultInstanceStrategy.start(ManagedServlet.java:215) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
	... 27 more
Caused by: java.lang.IllegalArgumentException: Can not set eartest.ejb.api.Hello field eartest.war.MyServlet.hello to eartest.ejb.api.Hello$$$view17
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) [rt.jar:1.8.0_20]
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) [rt.jar:1.8.0_20]
	at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) [rt.jar:1.8.0_20]
	at java.lang.reflect.Field.set(Field.java:758) [rt.jar:1.8.0_20]
	at org.jboss.as.ee.component.ManagedReferenceFieldInjectionInterceptorFactory$ManagedReferenceFieldInjectionInterceptor.processInvocation(ManagedReferenceFieldInjectionInterceptorFactory.java:108)
	at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
	at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53)
	at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
	at org.jboss.as.ee.component.AroundConstructInterceptorFactory$1.processInvocation(AroundConstructInterceptorFactory.java:28)
	at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
	at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45) [wildfly-ee-8.2.0.Final.jar:8.2.0.Final]
	at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
	at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64)
	at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
	at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:326)
	at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80)
	at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
	at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
	at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:160)
	... 32 more


Lean example of integration test Maven project for WildFly


Posted on Monday Feb 23, 2015 at 11:20PM in Technology


I created similar example before, but it was redundant. I created more lean version so leave here with some notes. check my GitHub repository for details.

The project contains AppServer class, which extends ExternalResource so it can be used with @Rule annotation of JUnit as follows. note that mavenit is the name of WAR file to be tested.

public class HelloImplIT {

    @ClassRule
    public static AppServer appServer = new AppServer();
    private static Hello sut;

    @BeforeClass
    public static void beforeClass() {
        sut = appServer.lookup("mavenit", HelloImpl.class, Hello.class);
    }

    @Test
    public void test() {
        Assert.assertEquals("Hello world!", sut.hello());
    }
}

The project is easy to use with both of IDE and standalone. to run IT classes with IDE, you need to launch the application server, deploy the project as WAR package, then run a IT class from IDE. if you launched the server at not 8080 port, specify the port in app-server.port system property.

To run IT classes in standalone Maven, use following command. it automatically launches WildFly instance with port offset of 30000, deploy the WAR file, running IT classes, undeploy the WAR and stops WildFly. the command is intended to use from a Jenkins job.

mvn verify -Pintegration-test-with-wildfly \
 -Djava.home=/Library/Java/JavaVirtualMachines/jdk8/Contents/Home/jre \
 -Djboss-as.home=/Users/kyle/servers/wildfly-8.2.0.Final \
 -Dwildfly.port=39990 \
 -Dapp-server.port=38080 \
 -Dwildfly.jvmArgs="-Djboss.server.base.dir=/Users/kyle/servers/wildfly-8.2.0.Final/standalone-mavenit -Djboss.socket.binding.port-offset=30000 -ea"

You can configure following parameters through command line argument:

  • JAVA_HOME-Djava.home

  • WildFly distribution ⇒ -Djboss-as.home

  • jboss.server.base.dir ⇒ inside -Dwildfly.jvmArgs

  • Port offset ⇒ -Djboss.socket.binding.port-offset inside -Dwildfly.jvmArgs. you need to set -Dwildfly.port and -Dapp-server.port accordingly.


Switching EJB remote interface to local interface accordingly to environment


Posted on Monday Feb 23, 2015 at 01:33PM in Technology


Sometimes I need to create both of remote and local interface for EJBs. most of cases that were for integration testing. usually I used this way but that way still has some disadvantages as follows:

  • Annoying creation of both of interface (local and remote) is needed for all of each EJBs

  • Remote interface is redundant for most cases in production environment

To overcome these issues, I moved declarations of EJB from annotation to ejb-jar.xml. XML files are easy to be filtered with build tools such as Maven plugins. consider following case:

Business interface

public interface MyBean {
    String hello();
}

Implementation

public class MyBeanImpl implements MyBean {
    @Override
    public String hello() {
        return "Hello";
    }
}

Injection point

@WebServlet(name = "MyServlet", urlPatterns = "/")
public class MyServlet extends HttpServlet {
    @EJB
    MyBean myBean;
...
}

Test class

public class MyBeanIT {
    static Context ctx;
    static MyBean myBean;

    @BeforeClass
    public static void before() throws Exception {
        Properties props = new Properties();
        // ... put application server specific configuration here ...
        ctx = new InitialContext(props);
        myBean = (MyBean) ctx.lookup("ejb:/ejbxmltest//MyBeanImpl!org.nailedtothex.ejbxmltest.MyBean");
    }

    @AfterClass
    public static void after() throws Exception {
        ctx.close();
    }

    @Test
    public void test() throws Exception {
        org.junit.Assert.assertEquals("Hello", myBean.hello());
    }
}

ejb-jar.xml

<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
         version="3.1">
    <enterprise-beans>
        <session>
            <ejb-name>MyBeanImpl</ejb-name>

            <!-- Will be replaced by business-local with replacer-plugin for production -->
            <business-remote>org.nailedtothex.ejbxmltest.MyBean</business-remote>

            <ejb-class>org.nailedtothex.ejbxmltest.MyBeanImpl</ejb-class>
            <session-type>Stateless</session-type>
        </session>
    </enterprise-beans>
</ejb-jar>

Remote interface and bean definition are presented in ejb-jar.xml instead of annotations. that definition will be used by IDE as default. EJBs will be deployed with a remote interface to the application server in development environment so we can test the bean through remote interface. a trick is in a profile named business-local in pom.xml which intended to use for production environment:

<profile>
	<id>business-local</id>
	<build>
		<!-- Following plugin definitions will be ignored by IDEA -->
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<configuration>
					<warSourceExcludes>WEB-INF/ejb-jar.xml</warSourceExcludes>
				</configuration>
			</plugin>
			<plugin>
				<groupId>com.google.code.maven-replacer-plugin</groupId>
				<artifactId>replacer</artifactId>
				<version>1.5.3</version>
				<executions>
					<execution>
						<phase>prepare-package</phase>
						<goals>
							<goal>replace</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<file>src/main/webapp/WEB-INF/ejb-jar.xml</file>
					<outputFile>target/${project.artifactId}/WEB-INF/ejb-jar.xml</outputFile>
					<token><![CDATA[(?<=</?)business-remote(?=>)]]></token>
					<value>business-local</value>
				</configuration>
			</plugin>
		</plugins>
	</build>
</profile>

maven-replacer-plugin replaces all of business-remote elements by business-local and put it into WEB-INF directory in the target directory, and tell maven-war-plugin to stop copying original WEB-INF/ejb-jar.xml so all of remote interfaces will be local interfaces in production environment. it is disabled by default and you have to enable it with invoke Maven with -P business-local argument. as to injection point (MyServlet) we don’t need to make any modification. @EJB or @Inject will work nevertheless whether the interface is local or remote.

Actually I really want to use Arquillian instead of remote EJB but unfortunately it doesn’t have some flexibility on my use case such as control of deployment timing at the present time.

The project used in test is available in my GitHub repository. the test was done with WildFly 8.2.0.Final.

CAUTION: invoking EJBs via local interface will call by reference but invoking via remote interface will call by value. you will get serious problems that different behavior between invoking local and remote interfaces. consider keep using remote interface on production (with accepting some performance degradation) or using modern testing framework such as Arquillian if necessary.


Avoiding EJBException wrapping


Posted on Sunday Mar 02, 2014 at 03:33PM in Technology


How to avoid EJBException wrapping.

Environment

  • WildFly 8.0.0.Final
  • Oracle JDK7u51

How?

  • We can avoid EJBException wrapping with @ApplicationException annotation.
  • Also API classes (e.g. NoResultException) can be specified in WEB-INF/ejb-jar.xml.

Project

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>org.nailedtothex</groupId>
    <artifactId>avoidejbexception</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

Stateless Session Bean

package org.nailedtothex.ex;

import javax.ejb.Stateless;
import javax.persistence.NoResultException;

@Stateless
public class MyEJB {

    public void throwIllegalArgumentException(){
        throw new IllegalArgumentException();
    }

    public void throwNoResultException(){
        throw new NoResultException();
    }

    public void throwMyApplicationException(){
        throw new MyApplicationException();
    }

}

Servlet

package org.nailedtothex.ex;

import java.io.IOException;

import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/*")
public class MyServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Inject
    MyEJB myEJB;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        StringBuilder sb = new StringBuilder();

        try{
            myEJB.throwNoResultException();
        }catch(Exception e){
            sb.append("throwNoResultException() thrown: ").append(e.getClass()).append('\n');
        }

        try{
            myEJB.throwIllegalArgumentException();
        }catch(Exception e){
            sb.append("throwIllegalArgumentException() thrown: ").append(e.getClass()).append('\n');
        }

        try{
            myEJB.throwMyApplicationException();
        }catch(Exception e){
            sb.append("throwMyApplicationException() thrown: ").append(e.getClass());
        }

        System.out.println(sb);
    }
}

MyApplicationException

package org.nailedtothex.ex;

import java.io.Serializable;

import javax.ejb.ApplicationException;

@ApplicationException
public class MyApplicationException extends RuntimeException implements Serializable {

    private static final long serialVersionUID = 1L;

}

/WEB-INF/ejb-jar.xml

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" version="3.1"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">

    <assembly-descriptor>
        <application-exception>
            <exception-class>javax.persistence.NoResultException</exception-class>
            <rollback>true</rollback>
        </application-exception>
    </assembly-descriptor>

</ejb-jar>
  • Taken from [1].

Log

16:21:39,152 INFO  [stdout] (default task-13) throwNoResultException() thrown: class javax.persistence.NoResultException
16:21:39,152 INFO  [stdout] (default task-13) throwIllegalArgumentException() thrown: class javax.ejb.EJBException
16:21:39,153 INFO  [stdout] (default task-13) throwMyApplicationException() thrown: class org.nailedtothex.ex.MyApplicationException

Whole Log

16:21:39,146 ERROR [org.jboss.as.ejb3.invocation] (default task-13) JBAS014134: EJB Invocation failed on component MyEJB for method public void org.nailedtothex.ex.MyEJB.throwIllegalArgumentException(): javax.ejb.EJBException: java.lang.IllegalArgumentException
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:190) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:275) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:340) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:239) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.invocationmetrics.WaitTimeInterceptor.processInvocation(WaitTimeInterceptor.java:43) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:95) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:55) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:326)
    at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:448)
    at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:326)
    at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
    at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:185)
    at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:182)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
    at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:73)
    at org.nailedtothex.ex.MyEJB$$$view1064.throwIllegalArgumentException(Unknown Source) [classes:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_51]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_51]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_51]
    at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_51]
    at org.jboss.weld.util.reflection.Reflections.invokeAndUnwrap(Reflections.java:401) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:99) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.jboss.weld.bean.proxy.InjectionPointPropagatingEnterpriseTargetBeanInstance.invoke(InjectionPointPropagatingEnterpriseTargetBeanInstance.java:65) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:100) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.nailedtothex.ex.MyEJB$Proxy$_$$_Weld$EnterpriseProxy$.throwIllegalArgumentException(Unknown Source) [classes:]
    at org.nailedtothex.ex.MyServlet.doGet(MyServlet.java:30) [classes:]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final]
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.security.handlers.AuthenticationCallHandler.handleRequest(AuthenticationCallHandler.java:52) [undertow-core-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final]
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146) [undertow-servlet-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:168) [undertow-core-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:687) [undertow-core-1.0.0.Final.jar:1.0.0.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_51]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_51]
    at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_51]
Caused by: java.lang.IllegalArgumentException
    at org.nailedtothex.ex.MyEJB.throwIllegalArgumentException(MyEJB.java:10) [classes:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_51]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_51]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_51]
    at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_51]
    at org.jboss.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53)
    at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:63)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:407)
    at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doMethodInterception(Jsr299BindingsInterceptor.java:82) [wildfly-weld-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:93) [wildfly-weld-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:63)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53)
    at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:63)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.invocationmetrics.ExecutionTimeInterceptor.processInvocation(ExecutionTimeInterceptor.java:43) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.jpa.interceptor.SBInvocationInterceptor.processInvocation(SBInvocationInterceptor.java:47)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:407)
    at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:46) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:83) [wildfly-weld-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45) [wildfly-ee-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.InitialInterceptor.processInvocation(InitialInterceptor.java:21)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
    at org.jboss.as.ee.component.interceptors.ComponentDispatcherInterceptor.processInvocation(ComponentDispatcherInterceptor.java:53)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.interceptors.NonPooledEJBComponentInstanceAssociatingInterceptor.processInvocation(NonPooledEJBComponentInstanceAssociatingInterceptor.java:59) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:273) [wildfly-ejb3-8.0.0.Final.jar:8.0.0.Final]
    ... 70 more

16:21:39,152 INFO  [stdout] (default task-13) throwNoResultException() thrown: class javax.persistence.NoResultException
16:21:39,152 INFO  [stdout] (default task-13) throwIllegalArgumentException() thrown: class javax.ejb.EJBException
16:21:39,153 INFO  [stdout] (default task-13) throwMyApplicationException() thrown: class org.nailedtothex.ex.MyApplicationException
  • Stacktraces of application exception were not logged.

Specifying java.lang.RuntimeException as an application exception in ejb-jar.xml

log

16:26:13,256 INFO  [stdout] (default task-12) throwNoResultException() thrown: class javax.persistence.NoResultException
16:26:13,256 INFO  [stdout] (default task-12) throwIllegalArgumentException() thrown: class java.lang.IllegalArgumentException
16:26:13,256 INFO  [stdout] (default task-12) throwMyApplicationException() thrown: class org.nailedtothex.ex.MyApplicationException
  • Seems to be working.

Specifying java.lang.Exception as an application exception in ejb-jar.xml

log

16:26:54,294 INFO  [stdout] (default task-1) throwNoResultException() thrown: class javax.ejb.EJBException
16:26:54,294 INFO  [stdout] (default task-1) throwIllegalArgumentException() thrown: class javax.ejb.EJBException
16:26:54,294 INFO  [stdout] (default task-1) throwMyApplicationException() thrown: class org.nailedtothex.ex.MyApplicationException
  • Not working?

References

  1. EJB steals JPA's exceptions? | Community
  2. java - EJB 3.1 application deployed as WAR-only: What about ejb-jar.xml? - Stack Overflow
  3. java - How to include ejb-jar.xml in .war - Stack Overflow
  4. Deployment Descriptors used In WildFly - WildFly 8 - Project Documentation Editor