surefire parallel threadCount is ignored (JUnit 4) - junit4

I've seen quite a few topics dealing with running JUnit tests in parallel with maven surefire, but I haven't seen an answer dealing with this particular issue.
In short: test methods are executing in parallel (good news there), but the prop doesn't serve to limit my threads. The ultimate goal is to parallelize my web driver and appium runs, but I'd like to be able to control the total possible threads first.
The code snippets below are from a dummy project just for demonstration's sake. Following the apache documentation, it doesn't look like there's a whole lot more to it than the below.
pom.xml
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<parallel>methods</parallel>
<threadCountMethods>2</threadCountMethods>
</configuration>
</plugin>
</plugins>
</build>
ExampleTest.class
public class ExampleTest {
#Test
public void one() throws InterruptedException {
Thread.sleep(5000);
}
#Test
public void two() throws InterruptedException {
Thread.sleep(5000);
}
#Test
public void three() throws InterruptedException {
Thread.sleep(5000);
}
#Test
public void four() throws InterruptedException {
Thread.sleep(5000);
}
#Test
public void five() throws InterruptedException {
Thread.sleep(5000);
}
#Test
public void six() throws InterruptedException {
Thread.sleep(5000);
}
#Test
public void seven() throws InterruptedException {
Thread.sleep(5000);
}
#Test
public void eight() throws InterruptedException {
Thread.sleep(5000);
}
#Test
public void nine() throws InterruptedException {
Thread.sleep(5000);
}
#Test
public void ten() throws InterruptedException {
Thread.sleep(5000);
}
}
I'd expect a full run of this class with the provided pom config to take a little longer than 25 seconds (10 sleeps for 5 seconds running two at a time). The actual runtime is a little more than 5 seconds:
Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.022 sec - in ExampleTest
Changing that threadCountMethods prop has no effect on the runtime (it looks like all methods are going in parallel without regard for the threadCount prop).
Any input would be greatly appreciated; thanks!

So after some more digging, I found a tiny little property called perCoreThreadCount found here. If not specified, that prop defaults to true. With a total of 8 cores on my machine, 2 threads per core (from the original pom config in the question) would mean up to 16 of those sample tests could run in 5ish seconds. Adding that prop and setting value to false in pom fixed all the trouble!

Related

NetBeans Junit5 Tests-Output ignore DisplayName Nested-Format

I do not get the names from the annoations "#DisplayName" as a test result in NetBeans. Only the names of the test functions are shown. The grouped display of the nested tests is also ignored.
Source code
#DisplayName("test facade")
public class TestFacadeTest {
#BeforeAll
public static void setUpClass() {
}
#AfterAll
public static void tearDownClass() {
}
#BeforeEach
public void setUp() {
}
#AfterEach
public void tearDown() {
}
#Test
#DisplayName("senseless test")
public void test(){
Assertions.assertTrue(true);
}
#Nested
#DisplayName("tests - compareStringNullSave")
class CompateStringNullSaveTestGroup {
#BeforeEach
public void setUp() {
}
#Test
#DisplayName("both identical")
public void Test1(){
String str1 = "Test123";
String str2 = "Test123";
Assertions.assertTrue(TestFacade.compareStringNullSave(str1, str2));
Assertions.assertTrue(TestFacade.compareStringNullSave(str2, str1));
}
#Test
#DisplayName("Identical text but different uppercase and lowercase letters")
public void Test2(){
String str1 = "Test123";
String str2 = "test123";
Assertions.assertFalse(TestFacade.compareStringNullSave(str1, str2));
Assertions.assertFalse(TestFacade.compareStringNullSave(str2, str1));
}
}
}
Extract from the pom.xml
<dependencies>
[...]
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
[...]
</dependencies>
<build>
<plugins>
[...]
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<properties>
<configurationParameters>
junit.jupiter.conditions.deactivate = *
junit.jupiter.extensions.autodetection.enabled = true
junit.jupiter.testinstance.lifecycle.default = per_class
</configurationParameters>
</properties>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
What do I have to set so that the test display in NetBeans shows the DisplayNames and uses the nested grouping?
NetBeans version: 12.0
Java version: 11 (OpenJDK)
Maven added support for the #Display annotation in the 3.0.0.0-M4 version of the surefire plugin. Also, you need to configure the parameters of statelessTestsetReporter and statelessTestsetInfoReporter extensions to allow for NetBeans to match display names correctly.
So currently (01.2021), you can use 3.0.0.0-M4 or newer versions of the surefire plugin, and the version of JUnit should be more than 5.5.2. Something like that should work:
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<statelessTestsetReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5Xml30StatelessReporter">
<version>3.0</version>
<usePhrasedFileName>true</usePhrasedFileName>
<usePhrasedTestSuiteClassName>true</usePhrasedTestSuiteClassName>
<usePhrasedTestCaseClassName>true</usePhrasedTestCaseClassName>
<usePhrasedTestCaseMethodName>true</usePhrasedTestCaseMethodName>
</statelessTestsetReporter>
<statelessTestsetInfoReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoReporter">
<usePhrasedClassNameInRunning>true</usePhrasedClassNameInRunning>
</statelessTestsetInfoReporter>
<properties>
<configurationParameters>
junit.jupiter.conditions.deactivate = *
junit.jupiter.extensions.autodetection.enabled = true
junit.jupiter.testinstance.lifecycle.default = per_class
</configurationParameters>
</properties>
</configuration>
</plugin>
</plugins>
Here how it looks in my case:
#DisplayName("Display Name of class")
public class testClassSimple {
#Test
#DisplayName("Display name of method 1")
public void testMethod1() {
}
#Test
#DisplayName("Display name of method 2")
public void testMethod2() {
}
}
As for nested grouping and the #Nested annotation, currently, NetBeans doesn't support nested grouping of test results in the test result window. Probably it's better to use different classes for such tests instead of nested classes.

AspectJ execution pointcut on same method throwing NPE [duplicate]

I have 2 aspects that are applied on the same method.
When the method executes correctly I have no problem, everything is working fine and both aspects work as expected.
The problem is when the method throw an exception. In these cases, the first aspect re-throw correctly the exception, but the second aspect is generating a nullpointerexception.
I was able to reproduce the problem isolating the case on a unit test in a separated project.
Those are the aspects (actually I removed all the logic, at the moment they do nothing):
#Aspect
public class LogContextConstantAspect {
#Around("execution(* *(..)) && #annotation(logContextConstant)")
public Object aroundMethod(ProceedingJoinPoint joinPoint, LogContextConstant logContextConstant) throws Throwable {
try {
Object res = joinPoint.proceed();
return res;
} catch (Throwable e) {
throw e;
}
}
}
and
#Aspect
public class LogExecutionTimeAspect {
#Around("execution(* *(..)) && #annotation(logExecutionTime)")
public Object around(ProceedingJoinPoint joinPoint, LogExecutionTime logExecutionTime) throws Throwable {
try {
Object res = joinPoint.proceed();
return res;
} catch (Throwable e) {
throw e;
}
}
}
while those are the 2 custom annotation that I implemented
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface LogExecutionTime {
String paramKey() default "execution_time";
}
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.TYPE})
#Documented
public #interface LogContextConstant {
String name();
String value();
}
then I created a simple class with the following methods
public class AspectSimple {
public int execute() {
System.out.println("ok");
return 1;
}
public int failSimple() throws CustomException {
throw new CustomException("ko");
}
#LogExecutionTime
public int failWithAspect1() throws CustomException {
throw new CustomException("ko");
}
#LogContextConstant(name="test", value = "test")
public int failWithAspect2() throws CustomException {
throw new CustomException("ko");
}
#LogExecutionTime
#LogContextConstant(name="test", value = "test")
public int executeWithAspect() {
return 1;
}
#LogExecutionTime
#LogContextConstant(name="test", value = "test")
public int failWithAspect3() throws CustomException {
throw new CustomException("ko");
}
}
and finally this unit test
public class TestSample {
static AspectSimple as = null;
#BeforeAll
public static void setup() {
as = new AspectSimple();
}
#Test
public void test1() {
int res = as.execute();
assertEquals(1, res);
}
#Test
public void test2() {
int res = as.executeWithAspect();
assertEquals(1, res);
}
#Test
public void test3() {
try {
int res = as.failSimple();
} catch (CustomException e) {
assertNotNull(e);
} catch (Exception e) {
fail();
}
}
#Test
public void test4() {
try {
int res = as.failWithAspect1();
} catch (CustomException e) {
assertNotNull(e);
} catch (Exception e) {
fail();
}
}
#Test
public void test5() {
try {
int res = as.failWithAspect2();
} catch (CustomException e) {
assertNotNull(e);
} catch (Exception e) {
fail();
}
}
#Test
public void test6() {
try {
int res = as.failWithAspect3();
} catch (CustomException e) {
assertNotNull(e);
} catch (Exception e) {
fail();
}
}
}
All tests are running correctly, only the last one (test6) fails.
the application is running on java 8, with aspectj 1.9.4 and junit 5.
Here the complete 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>it.pivimarco.samples.aspects</groupId>
<artifactId>aspect-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-engine</artifactId>
<version>1.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>1.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>
org.baeldung.executable.ExecutableMavenJar
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<executions>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/Test*.java</include>
<include>**/*Test.java</include>
<include>**/*Tests.java</include>
<include>**/*TestCase.java</include>
</includes>
<properties>
<excludeTags>slow</excludeTags>
</properties>
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
</configuration>
</execution>
</executions>
<configuration>
<includes>
<include>**/Test*.java</include>
<include>**/*Test.java</include>
<include>**/*Tests.java</include>
<include>**/*TestCase.java</include>
</includes>
<properties>
<excludeTags>slow</excludeTags>
</properties>
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<target>1.8</target>
<source>1.8</source>
<parameters>true</parameters>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.11</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.4</version>
<scope>compile</scope>
</dependency>
</dependencies>
<configuration>
<source>1.8</source>
<target>1.8</target>
<proc>none</proc>
<complianceLevel>1.8</complianceLevel>
</configuration>
</plugin>
</plugins>
</build>
</project>
If I apply just a single aspect the CustomException is throwed as aspected,
but when both aspects are applied I'm getting a nullpointerexception.
I've also tried to declare the precedence of the aspects, using DeclarePrecedence annotation, but it didn't work
#DeclarePrecedence("it.pivimarco.samples.aspects.LogContextConstantAspect,it.pivimarco.samples.aspects.LogExecutionTimeAspect")
This is the stacktrace of the NPE
java.lang.NullPointerException
at it.pivimarco.samples.aspects.AspectSimple.failWithAspect3_aroundBody10(AspectSimple.java:35)
at it.pivimarco.samples.aspects.AspectSimple$AjcClosure11.run(AspectSimple.java:1)
at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:170)
at it.pivimarco.samples.aspects.LogContextConstantAspect.aroundMethod(LogContextConstantAspect.java:18)
at it.pivimarco.samples.aspects.AspectSimple.failWithAspect3(AspectSimple.java:35)
at it.pivimarco.samples.aspects.TestSample.test6(TestSample.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
I think you uncovered a bug in the AspectJ compiler (versions 1.9.3, 1.9.4) which does not occur in version 1.9.2, as I said in my comment. I have just created AspectJ bug ticket #552687 on your behalf. Please check there for further updates. For now you can just downgrade to 1.9.2 and continue working.
Update: AspectJ 1.9.5 with the bugfix is out. Please try again. My retest was successful.

Using embedded mongo in spring for local testing only

I'm trying to use the flapdoodle embedded mongo database ('de.flapdoodle.embed:de.flapdoodle.embed.mongo')
for local manual testing the way I'd use H2 for relational database testing. I only want the embedded mongo to start up when running under the 'local' SPring profile, but I can't figure out how to make it happen -- it just always starts under any profile.
I've tried adding #SpringBootApplication(exclude=EmbeddedMongoAutoConfiguration.class) to my application (thinking I could reimport that autoconfig to a single profile later) but that doesn't seem to have any affect.
Anyone know how to limit it to a single profile, in a way that will work when running in Eclipse as well as via Gradle?
I can think of two ways:
1- Load your dependency only in specific profile in maven or gradle
Maven
<profiles>
<profile>
<id>local</id>
<dependencies>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>2.0.4-SNAPSHOT</version>
</dependency>
</dependencies>
</profile>
</profiles>
Gradle
if (project.hasProperty('local')) {
dependencies {
compile 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:2.0.4-SNAPSHOT'
}
}
2- Using #Profile and #Import in your class
LoadEmbeded.java
#Profile(value = "local")
#Configuration
#Import(EmbeddedMongoAutoConfiguration.class)
public class LoadEmbeded {
}
Hope it can give your a idea about it
Edit 1:
I have tested my approach and made a very simple application. It works with #Profile. Here is what I tested.
#SpringBootApplication(exclude = EmbeddedMongoAutoConfiguration.class)
public class DemoApplication {
#Autowired
TestRepository repository;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Bean
CommandLineRunner runner() {
return args -> {
System.out.println(repository.save(new Test()));
System.out.println(repository.findAll());
};
}
}
#Repository
interface TestRepository extends MongoRepository<Test, String> {
}
#Document
class Test {
#Id
private String id;
public String getId() {
return id;
}
public Test setId(String id) {
this.id = id;
return this;
}
#Override
public String toString() {
return new ToStringBuilder(this)
.append("id", id)
.toString();
}
}
#Configuration
#Profile("local")
#Import(EmbeddedMongoAutoConfiguration.class)
class Load {
}
And application.properties
spring.profiles.active=local
When I changed active profile to something else but local, it throws exception during startup and complaining about connection of mongodb. But when I set it local, it works and shows me the id of saved test entity.
If still you are experiencing same problem, maybe one of your dependencies is loading the Embedded MongoDB again even you exclude it. Usually it should be with test dependencies. Check your dependencies.

Create new entity in broadleaf

Note : I am using PostgreSQL database
After the build and run table is not created in database
I do same as broadleaf documentation for create new entity:
1. **Created new interface** :
package com.mycompany.entity.ordereturn;
public interface OrderReturn {
Long getId();
void setId(Long id);
String getReason();
void setReason(String reason);
String getAddress();
void setAddress(String address);
}
Created new OrderReturnImpl class :
#Entity
#Table(name = "blc_order_return")
public class OrderReturnImpl implements OrderReturn{
#Id
#GeneratedValue(generator= "OrderReturnId")
#GenericGenerator(
name="OrderReturnId",
strategy="org.broadleafcommerce.common.persistence.IdOverrideTableGenerator",
parameters = {
#Parameter(name="segment_value", value="OrderReturnImpl"),
#Parameter(name="entity_name", value="com.mycompany.entity.ordereturn.OrderReturnImpl")
}
)
#Column(name = "OrderReturn_ID")
protected Long id;
#Column(name = "Reason")
protected String reason;
#Column(name = "Address")
protected String address;
#Override
public Long getId() {
// TODO Auto-generated method stub
return id;
}
#Override
public void setId(Long id) {
// TODO Auto-generated method stub
this.id = id;
}
#Override
public String getReason() {
// TODO Auto-generated method stub
return reason;
}
#Override
public void setReason(String reason) {
// TODO Auto-generated method stub
this.reason = reason;
}
#Override
public String getAddress() {
// TODO Auto-generated method stub
return address;
}
#Override
public void setAddress(String address) {
// TODO Auto-generated method stub
this.address = address;
}
}
Configure in persistence-core.xml file :
<persistence-unit name="blPU" transaction-type="RESOURCE_LOCAL">
// Added this line in name = "blPU"
<class>com.mycompany.controller.account.OrderReturnImpl</class>
<exclude-unlisted-classes/>
</persistence-unit>
Although you havent posted your full OrderReturnImpl.java file, you're probably missing the #Entity annotation (along with #Table annotation).
Please annotate your class accordingly.
OK i see a new edit and you now have the annotations. So the error still continues with these annotations?
if you want to create the database tables from the entities, please use
<property name="hibernate.hbm2ddl.auto">create</property>
One possible problem is with creating tables if you are running admin/site on standalone server. Try it on embedded tomcat or jetty.
configure:
In admin/resource/runtime-properties/development.properties
blPU.hibernate.hbm2ddl.auto=create
blCMSStorage.hibernate.hbm2ddl.auto=create
blSecurePU.hibernate.hbm2ddl.auto=create
In core/resource/runtime-properties/common-shared.properties
blPU.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
blSecurePU.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
blCMSStorage.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
blPU.hibernate.hbm2ddl.import_files_sql_extractor=org.broadleafcommerce.common.util.sql.importsql.DemoPostgresSingleLineSqlCommandExtractor
blSecurePU.hibernate.hbm2ddl.import_files_sql_extractor=org.broadleafcommerce.common.util.sql.importsql.DemoPostgresSingleLineSqlCommandExtractor
blCMSStorage.hibernate.hbm2ddl.import_files_sql_extractor=org.broadleafcommerce.common.util.sql.importsql.DemoPostgresSingleLineSqlCommandExtractor
database.properties populated with your data
Be sure to have:
PostgreSQL driver in [standaloneserver]/lib or as a library if you run on embedded servers
Invalidated IDE cache
Clean and install maven goals on all project (or on all three modules)
postgresql start database in pom's executions and postgresql dependency
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>postgres-start</id>
<configuration>
<target>
<echo message="Starting postgres database..."/>
<java fork="true" spawn="true" classname="org.postgresql.Driver"
classpathref="maven.plugin.classpath">
</java>
<echo message="Database started successfully"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1211</version>
</dependency>
</dependencies>

Excpetionmapper does not work with Wildfly Swarm but does work in Wildfly Server

I am trying to run a simple entity - controller - boundery application in WildFly Swarm. This works fine, however when I add an ExceptionMapper to catch the NotFoundException this does work on WildFly server 10 but not in WildFly swarm. Is this a bug in Shrinkwrap? Is this a bug in Wildfly Swarm? Or am I doing something wrong in Shrinkwrapping the deployment?
Here's the specific code for the Swarm Main class:
public class Main {
public static void main(String[] args) throws Exception {
Container container = new Container();
container.fraction(new DatasourcesFraction()
.jdbcDriver("h2", (d) -> {
d.driverClassName("org.h2.Driver");
d.xaDatasourceClass("org.h2.jdbcx.JdbcDataSource");
d.driverModuleName("com.h2database.h2");
})
.dataSource("demoDS", (ds) -> {
ds.driverName("h2");
ds.connectionUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
ds.userName("sa");
ds.password("sa");
})
);
// Prevent JPA Fraction from installing it's default datasource fraction
container.fraction(new JPAFraction()
.inhibitDefaultDatasource()
.defaultDatasource("jboss/datasources/demoDS")
);
container.start();
JAXRSArchive deployment = ShrinkWrap.create(JAXRSArchive.class);
deployment.addClasses(Customer.class);
deployment.addAsWebInfResource(new ClassLoaderAsset("META-INF/persistence.xml", Main.class.getClassLoader()), "classes/META-INF/persistence.xml");
deployment.addClass(CustomerService.class);
deployment.addResource(CustomerResource.class);
//BUG: The provider below is not working!
deployment.addClass(NotFoundExceptionMapper.class);
deployment.addAllDependencies();
container.deploy(deployment);
}
}
and here is my swarm demo pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.domain</groupId>
<artifactId>swarm-demo</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<version.wildfly-swarm.core>1.0.0.Beta2</version.wildfly-swarm.core>
<version.wildfly-swarm.plugin>1.0.0.Beta2</version.wildfly-swarm.plugin>
</properties>
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jaxrs-weld</artifactId>
<version>${version.wildfly-swarm.core}</version>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>ejb</artifactId>
<version>${version.wildfly-swarm.core}</version>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jpa</artifactId>
<version>${version.wildfly-swarm.core}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.191</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-plugin</artifactId>
<version>${version.wildfly-swarm.plugin}</version>
<configuration>
<mainClass>nl.paston.swarm.demo.Main</mainClass>
<jvmArguments>
<!-- Needs to be tuned for performance -->
<jvmArgument>-Xmx128m</jvmArgument>
</jvmArguments>
</configuration>
<!-- Needed for fat jar creation -->
<executions>
<execution>
<id>package</id>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
For comparison, this is my pom.xml for the Wildfly server application:
<?xml version="1.0" encoding="UTF-8"?>
<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.domain</groupId>
<artifactId>wildfly-demo</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<version.java-ee>7.0</version.java-ee>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${version.java-ee}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
For completeness, here is the code for the ExceptionMapper:
#Provider
public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> {
#Override
public Response toResponse(NotFoundException e) {
System.out.println("Exceptionmapper called!");
return Response.ok().build();
}
}
The boundery:
#Path("/customer")
#ApplicationScoped
public class CustomerResource {
#Inject CustomerService cs;
#GET #Path("/") #Produces(MediaType.APPLICATION_JSON)
public List<Customer> get() {
return cs.getAll();
}
}
The controller:
#Stateless
public class CustomerService {
#PersistenceContext
private EntityManager em;
public List<Customer> getAll() {
return em.createNamedQuery(Customer.FIND_ALL, Customer.class).getResultList();
}
}
and the entity:
#Entity #Table(name = "CUSTOMER")
#NamedQueries({#NamedQuery(name = Customer.FIND_ALL, query = "SELECT c FROM Customer c")})
#XmlRootElement
public class Customer implements Serializable {
public static final String FIND_ALL = "Customer.findAll";
private static final long serialVersionUID = 1L;
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(length = 40)
private String name;
public Customer() { }
public Customer(String name) { this.name = name; }
public int getId() { return id; }
protected void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// toString, equals and hashCode overrides omitted
}
This has been resolved with the latest release. Please take a look at http://wildfly-swarm.io/posts/announcement-1-0-0-beta7/
Bear in mind that since Beta6 we've been providing a BOM with all the necessary versions of the different parts of WildFly Swarm, so importing the BOM into depMan will give you the right versions
I just tried with the latest swarm, and it doesn't seem to be an issue. Maybe you upgrade it'll work?
https://github.com/johnament/wildfly-swarm-examples/blob/master/jaxrs/jaxrs-shrinkwrap/src/main/java/org/wildfly/swarm/examples/jaxrs/shrinkwrap/Main.java
I suspect the issue has to do with your NotFoundException. What is the definition of it? Where are you throwing it?