Why does my flapdoodle Embedded MongoDB test fail to run? (creating 'embeddedMongoServer' could not start process EOF) - mongodb

I'm having trouble getting my brand new project to build. I used https://start.spring.io/ to generate a fresh new Spring 2.0 MongoDB Maven project, and I want to have an embedded MongoDB database for my integration tests. The spring initializer added a dependency for de.flapdoodle.embed.mongo to that end.
But every time I try to run a "mvn clean package", I get the following error during my test:
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'embeddedMongoServer' defined in class path resource
[org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.class]:
Invocation of init method failed; nested exception is java.io.IOException:
Could not start process: <EOF>
at de.flapdoodle.embed.mongo.AbstractMongoProcess.onAfterProcessStart(AbstractMongoProcess.java:79) ~[de.flapdoodle.embed.mongo-2.0.3.jar:na]
at de.flapdoodle.embed.process.runtime.AbstractProcess.<init>(AbstractProcess.java:116) ~[de.flapdoodle.embed.process-2.0.2.jar:na]
at de.flapdoodle.embed.mongo.AbstractMongoProcess.<init>(AbstractMongoProcess.java:53) ~[de.flapdoodle.embed.mongo-2.0.3.jar:na]
at de.flapdoodle.embed.mongo.MongodProcess.<init>(MongodProcess.java:50) ~[de.flapdoodle.embed.mongo-2.0.3.jar:na]
at de.flapdoodle.embed.mongo.MongodExecutable.start(MongodExecutable.java:44) ~[de.flapdoodle.embed.mongo-2.0.3.jar:na]
at de.flapdoodle.embed.mongo.MongodExecutable.start(MongodExecutable.java:34) ~[de.flapdoodle.embed.mongo-2.0.3.jar:na]
at de.flapdoodle.embed.process.runtime.Executable.start(Executable.java:108) ~[de.flapdoodle.embed.process-2.0.2.jar:na]
What am I missing?
My Application file is pretty straightforward:
#SpringBootApplication
public class NewnewinternetApplication {
public static void main(String[] args) {
SpringApplication.run(NewnewinternetApplication.class, args);
}
}
My Config file is very simple:
#Configuration
#EnableMongoRepositories
#ComponentScan(basePackages = "com.snoop.dougg.newnewinternet")
public class AppConfig {
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/");
resolver.setSuffix(".html");
return resolver;
}
}
I have two simple controllers returning just static output for now.
I have a little document:
#Document(collection = "user")
public class User implements Serializable {
protected static final long serialVersionUID = -1L;
#Id
private String id;
private String username;
private String firstName;
private String lastName;
public User() {}
public User(String username, String firstName, String lastName) {
this.username = username;
this.firstName = firstName;
this.lastName = lastName;
}
//Getters, setters, and equals and hash code methods...
}
And then a silly little test:
#RunWith(SpringRunner.class)
//#SpringBootTest -> Doesn't work either
#DataMongoTest
public class NewnewinternetApplicationTests {
#Autowired
private MongoTemplate mongoTemplate;
#Test
public void sillyLittleTest() {
mongoTemplate.save(new User("sdoug", "Snoop", "Dougg"));
Assert.notNull(
mongoTemplate.find(
new Query(Criteria.where("firstName").is("Snoop")), User.class),
"Couldn't find by first name!");
}
}
And then my pom file, which I really just left alone:
<?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.snoop.dougg.newnewinternet</groupId>
<artifactId>NewNewInternet</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<name>NewNewInternet</name>
<description>A new new internet</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<azure.version>2.0.1</azure.version>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.M9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-active-directory-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-keyvault-secrets-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-boot-bom</artifactId>
<version>${azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>

I was in the same situation, and I could resolve it using #DirtiesContext on this way:
#DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class CommoditiesApplicationTests {
}

Commenting out the following lines in application.properties and placing them in a different profile can also work. I found it here
spring.data.mongodb.database=
spring.data.mongodb.host=
spring.data.mongodb.port=

Usually already running mongodb instance is the source of the issue. I would start with checking if anything occupies default mongodb port - 27017.

In my case the 32 bit mongodb client was downloaded instead of the 64 bit one.
embedded.mongo library uses BitSize class to determine the OS architecture. In my system System.getProperty("os.arch") was not returning a value listed in the if statement.
I solved the problem by setting os.arch system property to x86_64 (one of the values used by BitSize to return B64) in my application main.
#SpringBootApplication
public class Application {
public static void main(String[] args) {
System.setProperty("os.arch", "x86_64");
SpringApplication.run(Application.class, args);
}
}
Note: System.getProperty("os.arch") will return the wrong value if you use a 32 bit java version to run your application on a 64 bit system!

my error message was exactly like this
2022-03-15 10:57:00.053 WARN 7196 --- [ Test worker] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'embeddedMongoServer' defined in class path resource [org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.class]: Unsatisfied dependency expressed through method 'embeddedMongoServer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'embeddedMongoConfiguration' defined in class path resource [org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [de.flapdoodle.embed.mongo.config.MongodConfig]: Factory method 'embeddedMongoConfiguration' threw exception; nested exception is java.lang.IllegalStateException: Set the spring.mongodb.embedded.version property or define your own MongodConfig bean to use embedded MongoDB
so, I add property in my application.yml file.
spring.mongodb.embedded.version: 3.2.3
and, solved it.

chances are the instance of mongodb downloaded through the spring plugin is 32 & you are running on 64 bit java or vice versa. Please confirm if there is any other way you have identified the fix.

I had the pretty same scenario here, and solved it using
<dependency>
<groupId>com.github.fakemongo</groupId>
<artifactId>fongo</artifactId>
<version>2.1.1</version>
<scope>test</scope>
</dependency>
instead of de.flapdoodle.embed.mongo

In my case, the socket file was still around.
To get to the underlying issue, I wanted the console logging output, I put a breakpoint in the else clause of the AbstractMongoProcess::onAfterProcessStart (which is hit on failure).
Here you have access to the logWatch and can run a System.out.println(logWatch.output.toString()); in debug mode to get the mongo console out. For my issue, the output said SocketException: Address already in use
Trying commands suggested such as sudo lsof -iTCP -sTCP:LISTEN -n -P did not work for me (nothing listed in my case)
I found another SO answer that said to run ls -lrta /tmp | grep .sock
The .sock file was still there from a previous run (Apparently I had interrupted my tests)
Deleting this file solved the issue.

The error is due to the package de.flapdoodle.embed which was used for Embedded Mongo, use a stable version of it 3.5.0
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>3.5.0</version>
<scope>test</scope>
</dependency>
add it in the pom.file(add the version to it).Then update maven it should work fine

My case was a bit special, but maybe this help someone else too to resolve this.
If, by any chance, you are using win 10 and you have already a MongoDB running as a service (in my case it was an earlier version - v3.4 - running), then try to stop the service, and run the test afterwards.

Try to add #DirtiesContext to the test class level.

I deleted the 'mongo' dir in my appdata/temp and that is when I caught my McAfee quarantining my embedded mongo. I turned OFF McAfee and deleted the temp mongo again and then all ran great...

Same problem.
spring.data.mongodb.port was 27017 in application.properties. I changed it to 0. When 0 is used, a random port is assigned instead.
My Integration Test is like below:
#RunWith(SpringRunner.class)
#DataMongoTest
public class IntegrationTestIT { ... }
I'm using de.flapdoodle.embed:de.flapdoodle.embed.mongo:3.4.6.

I had the same issue. Refer to this github issue for the solution if your problem is related to flapdoodle: https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo/issues/427
Just increase the flapdoodle version >=3.5.0
and if possible increase also spring-boot version to the latest

Related

Spring Boot Admin Server and Client in the same application

I am using spring boot 2.5.1 with Java 11.
I am trying to create a SpringBoot Admin Server and Client in the same application, however when I start it, I get the following error in the console.
Ref: https://github.com/codecentric/spring-boot-admin
Error
Failed to register application as Application(name=PowWow,
managementUrl=http://localhost:8085/actuator,
healthUrl=http://localhost:8085/actuator/health,
serviceUrl=http://localhost:8085/) at spring-boot-admin
([http://localhost:8085/instances]): 401 : [no body]. Further attempts
are logged on DEBUG level
I have the following code in the Spring Boot application:
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.5.1</version>
</dependency>
application.properties
server.port=8085
spring.application.name=PowWow
logging.file.name=powwow-logfile.log
logging.logback.rollingpolicy.max-history=3
logging.logback.rollingpolicy.max-file-size=5MB
spring.boot.admin.client.url=http://localhost:8085
management.endpoints.web.exposure.include=*
management.endpoints.health.show-details=always
PowWowApplication.java
#SpringBootApplication
#EnableScheduling
#EnableAdminServer
public class PowWowApplication {
More info
I can access the following url, but it does not load the application: http://localhost:8085/applications
Question
Do you know why the application is not being registered? Is it because you cannot have a spring-boot-admin-starter-server and a spring-boot-admin-starter-client in the same application?
More info
I realised that the application.properties has:
web.access.username=user
web.access.password=password
So I also add the following to allow the client access:
spring.boot.admin.client.username=user
spring.boot.admin.client.password=password
This removes the above error, i.e. there is no longer a 401 error when starting the server, but the application console reports that the server is down:
Console log: No Errors
http://localhost:8085/actuator/health {"status":"UP"}
However, the details show there is a 401.
I resolved this by adding /actuator/** to the following:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/soapWS/**").permitAll().and()
.authorizeRequests().antMatchers("/actuator/**").permitAll()
.anyRequest().authenticated().and()
.httpBasic().and()
.csrf().disable();
}

Working example of Spring boot reactive and EventSource

I'm trying to have a working spring boot with reactive mongodb and EventSource.
However, I'm facing issues with the repetitive reopening of the connection because it's closed by the server. I even have some doubt if this could really work since I didn't find any working example with a reactive db and Event source...
Could you please point me to a working example or tell me what's wrong with my code?
Here the main parts of the code:
pom.xml
<properties>
<java.version>1.8</java.version>
<junit-jupiter.version>5.3.2</junit-jupiter.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
</parent>
<dependencies>
<!-- webflux reactive -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<!-- exclude junit 4, prefer junit 5 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- junit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
As you see in the pom, I'm using the embedded tomcat (I already tried with Netty, the default spring boot server...).
Also, I'm deploying the app to any remote server but just trying on my local (windows 10).
Web:
let source = new EventSource("/comment/stream");
source.addEventListener("message", function (event) {
// These events are JSON, so parsing and DOM fiddling are needed
var comment = JSON.parse(event.data);
console.log(comment );
});
source.addEventListener("error", function (event) {
console.log("error", event);
this.close();
});
RestController:
#RestController
public class CommentController {
#Autowired
private CommentRepository commentRepository;
#PostMapping(path = "/comment")
public Mono<Comment> comment(#RequestBody Comment comment) {
return this.commentRepository.save(comment);
}
#GetMapping(path = "/comment/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Comment> feed() {
return this.commentRepository.findAll();
}
}
DB Repository:
#Repository
public interface CommentRepository extends ReactiveSortingRepository<Comment, String> {
Flux<Comment> findAll();
}
Again, the web client that uses EventSource, keeps reconnecting every second because the connection is closed by the server.
Thank you!
Im not really sure, you are giving us too little information as to why your connection is closing. No logs, and you are not disclosing anything about where it being deployed.
i will only answer this question based on personal experience. I deployed an application to heroku that uses event streams and they have a proxy/loadbalancer infront of every application that will kill any connection that does not send anything after up to 60 sec.
As mentioned here Why are event sources closed after 30-60 sec it confirmes what i have been noticing.
To work around this you can if using websockets implement ping/pong messages or if using ServerSentEvents as i did, i implemented keep alive messages.
.GET("", accept(TEXT_EVENT_STREAM), request -> ok()
.contentType(TEXT_EVENT_STREAM)
.header("Cache-Control", "no-transform")
.body(Flux.merge(myHandler.getEvents()),
Flux.interval(Duration.ofSeconds(15))
.map(aLong -> ServerSentEvent.builder()
.comment("keep alive")
.build())),
new ParameterizedTypeReference<List<MyClass>>() {}))
I have taken this code snippet from one of my projects. Here you can see that i merge with my current stream a flux that at given intervals (15 sec) will emit a ServerSentEvent with only a keep alive comment. Since it is a comment it will get ignored by the client.
Just need to mention, the regular stream myHandler.getEvents returns data wrapped in ServerSentEvents.

Connecting to a running Gemfire server

Using gfsh I have started a locator on my PC. How do I connect to this locator using spring-data-gemfire.
Here is the my locator
gfsh>start locator --name=locator1
Locator in /Users/adas/locator1 on 10.1.51.200[10334] as locator1 is currently online
Now I have the following class to connect to this locator
#ClientCacheApplication(locators = {
#ClientCacheApplication.Locator(host = "10.1.51.200", port = 10334)
})
#EnableEntityDefinedRegions(basePackageClasses = Person.class,
clientRegionShortcut = ClientRegionShortcut.LOCAL)
#EnableGemfireRepositories
public class GemfiretestApplication {
public static void main(String[] args) {
SpringApplication.run(GemfiretestApplication.class, args);
}
On compiling I get the following error
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gemfireCache': FactoryBean threw exception on object creation; nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:178)
Given the INCREDIBLY limited information provided (partial stacktrace, no versions, no maven/gradle build files) I could only venture a guess at your problem. I think #juanramos has the correct idea.
I'm testing with:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>Lovelave-SR6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
AND
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
Without the full stack trace I believe that I see your error. If then add the following exclusion, this problem disappears.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.4.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
If this does not solve your problem, please forward your complete stacktrace... or maybe the last "Caused by:...." statement and/or list of your dependencies.

Java-ee REST server with IntelliJ and Tomcat

I'm trying to implement a REST Server API using Java-ee following this tutorial. Instead of Glassfish, I use Tomcat.
I could develop a servlet
#WebServlet(name = "hello", urlPatterns = "/")
public class HelloWorld extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("=)");
}
}
And join http://localhost:9080/ I can see the smiling face. But when I try to access to the api path (http://localhost:9080/api/recommend/all) I also get the face. If I remove the servlet class, I get a 404 error. I suppose I need something else to build automatically the api but I don't know what.
Could someone tell my what is missing? What should I do?
Update:
In Intellij's Java Enterprise View I see:
Web > HelloWorld
RESTful WS > recommend > all
These are my api classes:
#ApplicationPath("/api")
public class REST_Config extends Application {
}
And the specific method
#Path("recommend")
public class RecommenderController {
#Path("/all")
#GET
#Produces("application/json")
public JsonArray getAll(){
JsonArrayBuilder builder = Json.createArrayBuilder();
builder.add(Json.createObjectBuilder().add("1", "2.5"));
return builder.build();
}
}
And the 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>TestREST</groupId>
<artifactId>TestREST</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
<build>
<finalName>TestREST</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
</build>
</project>
"Instead of Glassfish, I use Tomcat."
Look at this
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
This is nothing more than basically a bunch of interfaces for the EE spec. There is no implementation. Java EE servers will have the implementation. Tomcat is not an EE server. The only part of the EE spec it will definitely implements is the Servlet Specification. You are trying to work with the JAX-RS spec, where Tomcat for sure by default does not have an implementation for. So you need to add that implementation.
The easiest IMO to get started with, is Jersey. You can simple add this dependency
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.17</version>
</dependency>
And it will get you up and running. Keep the Jersey User Guide handy. It will come in use.
Also I don't know what JsonArray is, but what will happen when you run this is you will get some error similar to "No MessageBodyWriter found for JsonArray and media type application/json". You need to provider. If you are going to use the Java EE JSONP API, then you should add the this provider
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-processing</artifactId>
<version>2.17</version>
</dependency>
As you get to working alot with JSON, you wil find this API to be difficult to maintain. I'd recommend using Jackson. If you don't already know it, I'd suggest learning it. It offers simple POJO to JSON mapping. For Jackson, you can add this dependency
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.17</version>
</dependency>

Arquillian integration tests and OpenJPA enhancement

I'm working on a set of integration tests using arquillian and dbunit. I can run some of my tests just fine, but not the ones involving entities which have oneToMany relations with data in them. When running my tests I then get a PersistenceException:
Caused by: java.lang.NullPointerException
at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.setInverseRelation(JDBCStoreManager.java:451)
My test looks like this:
#RunWith(Arquillian.class)
#CreateSchema("sql/masterplanCreateTables.sql")
public class MasterPlanManagerBeanDbIT {
#Rule
public PersistenceUnitRule rule = new PersistenceUnitRule();
#Inject
private MasterplanManager instance;
#PersistenceContext
EntityManager entityManager;
#Deployment
public static WebArchive createDeployment() throws Exception {
return ShrinkWrap
.create(WebArchive.class, .....
}
#Test
#UsingDataSet("/data/integration/uttrans/masterplan/validData_dbInput.xml")
public void updateTrip_givenValidInput_expectsTripToBeUpdated() {
Trip input = givenTrips().get(0);
input.setNote("updated value");
Trip updated = instance.updateTrip(input);
checkEquality(input, updated);//checks field by field for equality
}
}
My pom.xml looks like this:
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.0.1.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
...
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>arquillian-tomee-embedded</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
...
</dependencies>
...
I did try the openjpa-maven-plugin to enhance the entities at build-time, but this will afaik alter the compiled entities which later will be deployed to our production environment (using deploy-time enhancement).
With that in mind, is it possible to enable deploy-time enhancement in my arquillian tests?
As I'm using openJpa, I found this link very helpful:
http://openejb.apache.org/javaagent.html
I am simply providing the openejb java-agent to the maven surefire plugin.
If you are using eclipse add -javaagent:{your java agent path} to the VM arguments for the test.
In my case I took the java agent directly from a TomEE installation.