Using Spring Boot Data to read MySQL data - mysql

I'm trying to create a framework to read data from MySQL using Spring Data. The end goal is to be able to write automated tests that could read data from two different MySQL dbs and compare the data (for example, to make sure data is replicating correctly). I'm currently having loads of trouble in actually getting the Spring code to work (I've never used Spring before, I've tried modifying some various tutorial code I've found on the web, but so far haven't gotten it working.)
Here's what I've got.
MySQL
table: credentials
columns: id (int), password_hash (string)
Has 4 entries in it.
Project layout:
src/main
groovy
domain
Credentials
repository
CredentialsRepository
resources
application.properties
src/test/groovy/
CredentialsTest
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.3.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
jar {
baseName = 'gs-accessing-data-jpa'
version = '0.1.0'
}
repositories {
mavenCentral()
maven { url "https://repository.jboss.org/nexus/content/repositories/releases" }
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.7'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.4.3.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '1.4.3.RELEASE'
testCompile 'junit:junit:4.11'
}
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/my_db
spring.datasource.username=my_user
spring.datasource.password=my_password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
Credentials.groovy
package domain
import org.springframework.data.annotation.Id
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Table
#Entity
#Table(name = 'credentials')
class Credentials {
#Id #GeneratedValue(strategy = GenerationType.AUTO) #Column(name='id')
int id
#Column(name='password_hash')
String passwordHash
protected Credentials() {}
#Override
String toString() {
"Credential: [id=${id}, passwordHash=${passwordHash}]"
}
}
CredentialsRepository.groovy
package repository
import domain.Credentials
import org.springframework.data.repository.CrudRepository
interface CredentialsRepository extends CrudRepository<Credentials, Integer> {
}
CredentialsTest.groovy
import domain.Credentials
import repository.CredentialsRepository
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
import static org.junit.Assert.assertEquals
#RunWith(SpringJUnit4ClassRunner.class) //#EnableJpaRepositories(['domain.Credentials'])
#SpringBootTest(classes = MysqlJpaDemoApplication.class)
class CredentialsTest {
#Autowired
CredentialsRepository credentialsRepository
#Test
void testLoadCredentials() {
List<Credentials> credentialsList = credentialsRepository.findAll() as ArrayList<Credentials>
assertEquals(20, credentialsList.size())
}
}
Running the testLoadCredentials test gives the following stacktrace:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'CredentialsTest': Unsatisfied dependency expressed through field 'credentialsRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'repository.CredentialsRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1225)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:386)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.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)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'repository.CredentialsRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1474)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1102)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 33 more
2016-12-28 14:14:32.638 INFO 39748 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#742ff096: startup date [Wed Dec 28 14:14:32 PST 2016]; root of context hierarchy
Process finished with exit code 255

Seems that the application class MysqlJpaDemoApplication that you're using to configure your tests is in the default (top-level) package. As Spring runs some checks when using #ComponentScan, it will prevent your application to scan the whole classpath.
You should move MysqlJpaDemoApplication to a new package, ie,com.example. Your source folder would look like this:
src/main
/groovy/com/example
|-- /domain
| |-- Credentials.groovy
|-- /repository
| |-- CredentialsRepository.groovy
|-- MysqlJpaDemoApplicatin.groovy

Looks like this is what got it to work:
com.example/
domain/
Credentials
repository/
CredentialsRepository
SpringConfig
Credentials.groovy
#Entity
#Table(name = 'credentials')
class Credentials {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
int id
#Column(name='password_hash')
String passwordHash
protected Credentials() {}
#Override
String toString() {
"Credential: [id=${id}, passwordHash=${passwordHash}]"
}
}
CredentialsRepository
interface CredentialsRepository extends CrudRepository<Credentials, Integer> {}
SpringConfig.groovy
#Configuration
#EnableAutoConfiguration
#ComponentScan('com.example')
class SpringConfig {}
CredentialsTest.groovy
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=SpringConfig.class)
#SpringBootTest(classes = SpringConfig.class)
class CredentialsTest {
#Autowired
CredentialsRepository credentialsRepository
#Test
void testLoadCredentials() {
List<Credentials> credentialsList = credentialsRepository.findAll() as ArrayList<Credentials>
assertEquals(4, credentialsList.size())
}
}

Related

Wired exception when using RedirectionException in Quarkus

Given this simple Jax-RS class:
package com.company.app;
import java.net.URI;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.RedirectionException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
#Path("/")
public class MyResource {
#GET
#Path("/")
public Response root() {
throw new RedirectionException(Status.TEMPORARY_REDIRECT, URI.create("/index.html"));
}
//...
}
In quarkus (using the resteasy extension) when I execute this rest-assured test:
#Test
public void testRootRedirect() {
RestAssuredConfig config = new RestAssuredConfig().redirect(new RedirectConfig().followRedirects(false));
given()
.config(config)
.when()
.get("/")
.then()
.statusCode(307)
.header("location", endsWith("/index.html"));
}
The test is green, but I see this stacktrace in the logs:
Oct 01, 2020 8:04:07 AM org.jboss.resteasy.core.ExceptionHandler handleWebApplicationException
ERROR: RESTEASY002010: Failed to execute
javax.ws.rs.RedirectionException: HTTP 307 Temporary Redirect
at com.unblu.qa.artifacts.PageResource.root(PageResource.java:30)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:638)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:504)
at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:454)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:456)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:417)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:391)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:68)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:488)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:259)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:160)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:163)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:245)
at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:132)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:37)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:94)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at java.base/java.lang.Thread.run(Thread.java:834)
at org.jboss.threads.JBossThread.run(JBossThread.java:479)
Is this stacktrace really a problem? The test is green…
How can I prevent this?

Failing to start my spring boot application due to 'javax.sql.DataSource' that could not be found

I am a beginner in spring boot and am trying to write a simple spring boot application.
My folder structure is as follows:
-> Project
-> build.gradle
-> settings.gradle
-> src/main/java
-> package
-> Main.java
-> UserController.java
-> UserRespository.java
-> dto
-> User.java
->src/main/resouces
-> application.properties
My build.gradle is as follows :
buildscript {
repositories {
jcenter()
}
dependencies {
classpath(
'org.springframework.boot:spring-boot-gradle- plugin:1.5.6.RELEASE'
)
classpath('mysql:mysql-connector-java:5.1.34')
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile(
'org.springframework.boot:spring-boot-starter-actuator',
'org.springframework.boot:spring-boot-starter-web',
'org.springframework.boot:spring-boot-starter-data-jpa'
)
compile('mysql:mysql-connector-java')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
The application.properties is as follows:
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://localhost:3306/user
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.database=MYSQL
spring.jpa.show-sql = true
My Main.java is as follows:-
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
};
}
I am able to successfully build the application. If I run the application , I get Unable to start application with the following stacktrace:
2017-08-14 20:43:02.976 WARN 27205 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2017-08-14 20:43:02.978 INFO 27205 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2017-08-14 20:43:03.007 INFO 27205 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-08-14 20:43:03.198 ERROR 27205 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration required a bean of type 'javax.sql.Data Source' that could not be found.
- Bean method 'dataSource' not loaded because #ConditionalOnProperty (spring.datasource.jndi-name) did not find property 'jndi-name'
- Bean method 'dataSource' not loaded because #ConditionalOnBean (types: org.springframework.boot.jta.XADataSourceWrapper; SearchStrategy: all) did not find any beans
Action:
Consider revisiting the conditions above or defining a bean of type 'javax.sql.DataSource' in your configuration.
I have checked the dependencies tree and can find both hibernate as well as mysql connector in it.
Have tried removing #EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) , in that case I get Cannot load driver class: com.mysql.jdbc.Driver
You should move the dto package inside into your Main.java class package, In your case it should be like src/main/java/package/dto
So when spring-boot scans, your entity will be visible to the scanner.
Make sure you have added the MySQL driver dependency
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>

Error, when i try validate Json from response with schema in soapUI

i use sopaUI 5.0.0 with libraries:
btf 1.2
jackson-annotations-2.0.1
jackson-core-2.8.1
jackson-coreutils-1.8
json-schema-core-1.2.5
json-schema-validator-2.2.6
I try do this code:
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.github.fge.jsonschema.core.report.ProcessingReport
import com.github.fge.jsonschema.main.JsonSchema
import com.github.fge.jsonschema.main.JsonSchemaFactory
def response = testRunner.testCase.getTestStepByName("getClientByID").getPropertyValue("response")
ObjectMapper mapper = new ObjectMapper()
JsonNode invoiceJSON = mapper.readTree(response)
JsonNode invoiceSchemaJSON = mapper.readTree(new File("C:\\test\\resources\\schems\\client-card-rs.json"))
log.info( invoiceSchemaJSON)
JsonSchemaFactory factory = JsonSchemaFactory.byDefault()
JsonSchema invoiceSchema = factory.getJsonSchema(invoiceSchemaJSON)
if (invoiceSchema.validInstance(invoiceJSON)) log.info("Response Validated!")
else {
testRunner.fail(invoiceSchema.validate(invoiceJSON).toString())
}
But script crash with error at line:
JsonSchemaFactory factory = JsonSchemaFactory.byDefault()
First,issued error:
"write_bigdecimal_as_plain"
Later
java.lang.NoClassDefFoundError: Could not initialize class com.github.fge.jsonschema.SchemaVersion
SoapUI error log:
2016-09-11 15:39:49,202 ERROR [errorlog] java.lang.NoClassDefFoundError: Could not initialize class com.github.fge.jsonschema.SchemaVersion
java.lang.NoClassDefFoundError: Could not initialize class com.github.fge.jsonschema.SchemaVersion
at com.github.fge.jsonschema.core.load.configuration.LoadingConfigurationBuilder.<init>(LoadingConfigurationBuilder.java:117)
at com.github.fge.jsonschema.core.load.configuration.LoadingConfiguration.byDefault(LoadingConfiguration.java:151)
at com.github.fge.jsonschema.main.JsonSchemaFactoryBuilder.<init>(JsonSchemaFactoryBuilder.java:67)
at com.github.fge.jsonschema.main.JsonSchemaFactory.newBuilder(JsonSchemaFactory.java:123)
at com.github.fge.jsonschema.main.JsonSchemaFactory.byDefault(JsonSchemaFactory.java:113)
at com.github.fge.jsonschema.main.JsonSchemaFactory$byDefault.call(Unknown Source)
at Script6.run(Script6.groovy:20)
at com.eviware.soapui.support.scripting.groovy.SoapUIGroovyScriptEngine.run(SoapUIGroovyScriptEngine.java:100)
at com.eviware.soapui.impl.wsdl.teststeps.WsdlGroovyScriptTestStep.run(WsdlGroovyScriptTestStep.java:154)
at com.eviware.soapui.impl.wsdl.panels.teststeps.GroovyScriptStepDesktopPanel$RunAction$1.run(GroovyScriptStepDesktopPanel.java:277)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Help pls.
The only solution that worked for me was using the json-schema-validator-2.2.8-lib.jar from com.github.java-json-tools (https://mvnrepository.com/artifact/com.github.java-json-tools/json-schema-validator/2.2.8) instead of com.github.fge (which supported the project till its 2.2.6 version). It is important to use the package of libs provided instead of collecting all the relevant dependencies manually. Somehow it doesn't want to work correctly.
I am using SoapUI 5.2.1 on Docker container built on top of an OpenJDK 8 image.

Exception thrown when posting JSON in JAX-RS app running on WLP 8.5.5.8

I have a very simple Java app using JAX-RS, running on WLP 8.5.5.8. When I post JSON that is a composite structure I get this error:
[ERROR ] Error occurred during error handling, give up! Invalid type
of value. Type: [java.util.LinkedHashMap] with value: [{d=e}] [ERROR
] SRVE0777E: Exception thrown by application class
'org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage:116'
java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: Invalid
type of value. Type: [java.util.LinkedHashMap] with value: [{d=e}]
at
org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:116)
at [internal classes] Caused by: org.apache.cxf.interceptor.Fault:
Invalid type of value. Type: [java.util.LinkedHashMap] with value:
[{d=e}] at
org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:76)
... 1 more Caused by: java.lang.IllegalArgumentException: Invalid
type of value. Type: [java.util.LinkedHashMap] with value: [{d=e}]
at com.ibm.json.java.JSONObject.put(JSONObject.java:241) ... 1 more
When I do a POST on the resource and the json object contains a property that is either a json array or a json object, the exception is thrown before the function is reached
Example JSON that causes this (if I remove the "c" property it works fine):
{
"a": "b",
"c": {
"d": "e"
}
}
The same error is thrown if "c" is an array:
{
"a": "b",
"c": [
{"d": "e"},
{"d": "f"},
{"d": "g"}
]
}
I have not added any libs of my own, all is what is included in WLP. If I run this example on WLP 8.5.5.3 it works fine. Any ideas what I am missing because I find it hard to believe that this simple sample expose a defect?
This is my resource:
RootResouce.java
package com.sample;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.ibm.json.java.JSONObject;
#Path("/hello")
public class RootResource {
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response postTest(JSONObject json) {
return Response.ok(json).build();
}
}
This is my app:
package com.sample;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class MyApp extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(RootResource.class);
return s;
}
}
This is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<servlet>
<description>Simple Test service</description>
<display-name>sample</display-name>
<servlet-name>sample</servlet-name>
<servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.sample.MyApp</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<enabled>true</enabled>
<async-supported>false</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>sample</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<display-name>SimpleTest</display-name>
</web-app>
Looking a little further with the code provided, I see this in the exception:
Caused by: java.lang.IllegalArgumentException: Invalid type of value. Type: [java.util.LinkedHashMap] with value: [{d=e}]
at com.ibm.json.java.JSONObject.put(JSONObject.java:241)
at org.codehaus.jackson.map.deser.MapDeserializer._readAndBind(MapDeserializer.java:244)
at org.codehaus.jackson.map.deser.MapDeserializer.deserialize(MapDeserializer.java:166)
at org.codehaus.jackson.map.deser.MapDeserializer.deserialize(MapDeserializer.java:24)
at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:1961)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:889)
at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:410)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1356)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1307)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:847)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:810)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:255)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:85)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307
Maybe the default json provider changed between jax-rs 1.1 and 2.0? Deserializing request data with Jackson into a json4j object is not going well. Setting the provider like this seems to allow it to work:
import com.ibm.websphere.jaxrs.providers.json4j.JSON4JArrayProvider;
import com.ibm.websphere.jaxrs.providers.json4j.JSON4JObjectProvider;
public class MyApp extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(RootResource.class);
s.add(JSON4JObjectProvider.class);
s.add(JSON4JArrayProvider.class);
return s;
}

Reflection error unit testing Java with Cucumber

I am running one simple cucumber test.
While running I am getting the following error.
java.lang.reflect.InvocationTargetException
My Runner class is -
package com.my.automation;
import cucumber.junit.Cucumber;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#Cucumber.Options(format = {"html:target/cucumber-html","json:target/cucumber.json",
"junit:target/cucumber-junit/cukey-junit_results.xml"},
features = {"src/test/resources/com/my/automation/cuketest/CukeTest.feature"} )
public class RunTest {
}