Amdatu + Jackson - Not Serializing ArrayList - RESTful Service with OSGi - jaxb

I am writing a Hello World web-service, and got stuck trying to serialize/deserialize the class list returned.
I have this code that is supposed to return a list of Conferences in Json:
#GET
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#Description("lists conferences")
public List<Conference> list() {
return agenda.listConferences();
}
Now, when I test the Service then I get this as response:
SEVERE: The system could not find a javax.ws.rs.ext.MessageBodyWriter or a DataSourceProvider class for the java.util.ArrayList type and application/json mediaT
ype. Ensure that a javax.ws.rs.ext.MessageBodyWriter exists in the JAX-RS application for the type and media type specified.
Nov 16, 2013 2:49:00 PM org.apache.wink.server.internal.RequestProcessor logException
INFO: The following error occurred during the invocation of the handlers chain: WebApplicationException (500 - Internal Server Error) with message 'null' while
processing GET request sent to http://localhost:8080/conferences
If I return the class Conference it works and returns the respective Json of the class, but if I make it return a list of conferences then it throws this exception.
I am using these bundles to manage the RESTful service:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.amdatu.web</groupId>
<artifactId>org.amdatu.web.rest.wink</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.amdatu.web</groupId>
<artifactId>org.amdatu.web.rest.jaxrs</artifactId>
<version>1.0.0</version>
</dependency>
Anybody knows why?

The reason is that you are using an old version of Amdatu Wink. The current version is 1.0.6. Jackson support was not available yet in the version you are using.

Related

Problems configuring clustered Vertx Eventbus in Quarkus

I'm using:
Quarkus 1.6.1.Final
Vertx 3.9.1 (provided by quarkus-vertx dependency, see pom.xml below)
And I can't get the clusered Eventbus working. I've followed the instructions listed here:
https://vertx.io/docs/vertx-hazelcast/java/
I've also enabled clustering in Quarkus:
quarkus.vertx.cluster.clustered=true
quarkus.vertx.cluster.port=8081
quarkus.vertx.prefer-native-transport=true
quarkus.http.port=8080
And here is my pom.xml:
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-mutiny</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-hazelcast</artifactId>
<version>3.9.2</version>
<exclusions>
<exclusion>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
</exclusion>
<!-- <exclusion>-->
<!-- <groupId>com.hazelcast</groupId>-->
<!-- <artifactId>hazelcast</artifactId>-->
<!-- </exclusion>-->
</exclusions>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.hazelcast</groupId>-->
<!-- <artifactId>hazelcast-all</artifactId>-->
<!-- <version>3.9</version>-->
<!-- </dependency>-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<classifier>linux-x86_64</classifier>
</dependency>
</dependencies>
And the error I get is the following:
Caused by: java.lang.ClassNotFoundException: com.hazelcast.core.MembershipListener
As you can see in my pom.xml, I've also added the dependency hazelcast-all:3.9 and excluded the hazelcast dependency from vertx-hazelcast:3.9.2, then this error disappears but another comes up:
Caused by: com.hazelcast.config.InvalidConfigurationException: cvc-complex-type.2.4.a: Invalid content was found starting with element '{"http://www.hazelcast.com/schema/config":memcache-protocol}'. One of '{"http://www.hazelcast.com/schema/config":public-address, "http://www.hazelcast.com/schema/config":reuse-address, "http://www.hazelcast.com/schema/config":outbound-ports, "http://www.hazelcast.com/schema/config":join, "http://www.hazelcast.com/schema/config":interfaces, "http://www.hazelcast.com/schema/config":ssl, "http://www.hazelcast.com/schema/config":socket-interceptor, "http://www.hazelcast.com/schema/config":symmetric-encryption, "http://www.hazelcast.com/schema/config":member-address-provider}' is expected.
Am I doing something wrong or forgetting something, or is this simply a bug in Quarkus or in Vertx ?
Thx in advance for any help.
I think the most probable reason of your issue is that you are using the quarkus-universe-bom which enforces a version of Hazelcast (we have an Hazelcast extension there) which is not compatible with vertx-hazelcast.
Check your dependency tree with mvn dependency:tree and make sure the Hazelcast artifacts are of the version required by vertx-hazelcast.
Another option would be to simply use the quarkus-bom which does not enforce an Hazelcast version and let vertx-hazelcast drag the dependency by itself.
It seems like a bug in Quarkus and this issue is related to:
https://github.com/quarkusio/quarkus/issues/10889
Bringing this from its winter sleep...
I am looking to use quarkus 2 + vert.x 4 and use either the shared data vert.x api or vert.x cluster manager in order to achieve an in-process, distributed cache (as opposed to an external dist. cache cluster)
What's unclear to me, also by looking at the git issue described above (thats still open), is if I can count on these APIs working for me at this time with the versions I mentioned.
Any comments will be great!
Thanks in advance...
[UPDATE]: looks like the clustered cache works with no issues using the shared data API along with quarkus, vertx, hazlecast & mutiny bindings for vertx (all with latest versions).
all I needed to do is set quarkus.vertx.cluster.clustered=true in quarkus properties file, use vertx.sharedData().getClusterWideMap implementation for the distrubuted cache and add gradle/maven 'io.vertx:vertx-hazelcast:4.3.1' support.
in general, thats all it took for a small poc code.
thanks

Coverting Java class to Json schema - FasterXML / jackson-module-jsonSchema

I am playing with some Spring Boot code to convert a java class to a Json schema and am getting strange behavior just by addin the dependency to the POM file as in
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jsonSchema</artifactId>
<version>2.9.4</version>
</dependency>
the error I am getting is:
The Bean Validation API is on the classpath but no implementation could be found
Action:
Add an implementation, such as Hibernate Validator, to the classpath
Any suggestion on reading on this or resolving.
Thanks.
Yes this comes because the artifact mentioned by you depends on:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
But this is only the validation API, a real validator that can do the 'real' work has to be added.
It would be interesting to see your pom.xml because many Spring Boot Starters already come with a validation implementation, e.g.:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
…comes with…
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-parent</artifactId>
</dependency>
By the way, the behavior described by you is also documented in this Spring Boot issue.
It will be fixed with this pull request which mandates a validation implementation only if a validation action is really performed (#Validated).

ArgumentMatchers not working after PowerMockito version update

I have an partial Mock that is not working anymore after an update from PowerMock 1.4.8 to 1.7.0RC4 to solve a sonar/jacoco incompatibility that was lowing the code coverage. After that, all the mocks that use matchers as parameters are not being called. The code looks like:
Calculator calc = mock(Calculator.class);
when(calc.getA()).thenReturn(new BigDecimal("1"));
when(calc.getB()).thenReturn(new BigDecimal("2"));
when(calc.calculate(any(Date.class), anyInt(), any(MyObject.class))).thenCallRealMethod();
The last mock method is never call when passing real parameters. I notice that this only happens due the use of Matchers of non-primitive types such as MyObject. Can anyone help me with this issue?
My pom.xml:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.0RC4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>1.7.0RC4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>1.7.0RC4</version>
<scope>test</scope>
</dependency>
PS: I am already using ArgumentMatchers instead of Matchers api.
Thanks in advance

Cannot subclass final class when using testng

In my project there is requirement where in I need to mock final class.
I am using Test-NG for unit tests.
I tried different things to mock but failed to do so. I also checked different stack overflow posts.
When running testng test case I am getting below error -
java.lang.IllegalArgumentException: Cannot subclass final class class com.AskStateParams
at org.mockito.cglib.proxy.Enhancer.generateClass(Enhancer.java:447)
at org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217)
at org.mockito.cglib.proxy.Enhancer.createHelper(Enhancer.java:378)
at org.mockito.cglib.proxy.Enhancer.createClass(Enhancer.java:318)
at org.mockito.internal.creation.jmock.ClassImposterizer.createProxyClass(ClassImposterizer.java:110)
at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:62)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:110)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:60)
In pom.xml am using below dependencies -
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.8</version>
<optional>true</optional>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-mockito-release-full</artifactId>
<version>1.5.1</version>
<classifier>full</classifier>
</dependency>
TestNG code is as below -
#RunWith(PowerMockRunner.class)
#PrepareForTest(AskStateParams.class)
public class TestProcessor17100AAskAmount extends AbstractPowerMockProcessorTest {
#Test
public void test() {
AskStateRequestParams askParams=PowerMockito.mock(AskStateRequestParams.class);
PowerMockito.when(askParams.getCallerInput()).thenReturn("1000");
PowerMockito.when(askParams.getResultCode()).thenReturn("Y");
PowerMockito.when(askParams.getMiString()).thenReturn("P=B");
Assert.assertEquals(baseProcessor.postProcess(requestContext), "amount");
}
}
First of all, if you use TestNG, I wonder why you have #RunWith(PowerMockRunner.class). It's part of jUnit module and integration with jUnit, not TestNG. Please, look at TestNG usage on PowerMock wiki.
Second mistake, I don't see in your code mockStatic(AskStateParams.class). Again, please, check documentation.

Log4J - SiftingAppender-like functionality

I work in a project that uses Log4J. One of the requirement is to create a separate log file for each thread; this itself was a odd issue, somewhat sorted by creating a new FileAppender on the fly and attaching it to the Logger instance.
Logger logger = Logger.getLogger(<thread dependent string>);
FileAppender appender = new FileAppender();
appender.setFile(fileName);
appender.setLayout(new PatternLayout(lp.getPattern()));
appender.setName(<thread dependent string>);
appender.setThreshold(Level.DEBUG);
appender.activateOptions();
logger.addAppender(appender);
Everything went fine until we realised that another library we use - Spring Framework v3.0.0 (which use Commons Logging) - does not play ball with the technique above – the Spring logging data is “seen” only by Appenders initialised from the log4.configuration file but not by the runtime created Appenders.
So, back to square one.
After some investigation, I found out that the new and improved LogBack has an appender - SiftingAppender – which does exactly what we need i.e. thread level logging on independent files.
At the moment, moving to LogBack is not an option, so, being stuck with Log4J, how can I achieve SiftingAppender-like functionality and keep Spring happy as well ?
Note: Spring is only used for JdbcTemplate functionality, no IOC; in order to “hook” Spring’s Commons Logging to Log4J I added this line in the log4j.properties file:
log4j.logger.org.springframework=DEBUG
as instructed here.
In Log4j2, we can now use RoutingAppender:
The RoutingAppender evaluates LogEvents and then routes them to a subordinate Appender. The target Appender may be an appender previously configured and may be referenced by its name or the Appender can be dynamically created as needed.
From their FAQ:
How do I dynamically write to separate log files?
Look at the RoutingAppender. You can define multiple routes in the configuration, and put values in the ThreadContext map that determine which log file subsequent events in this thread get logged to.
LogBack is accessed via the slf4j api. There is an adapter library called jcl-over-sjf4j which exposes the commons logging interface but makes all the logging to the slf4j API, which goes directly to the implementation - LogBack. If you are using maven, here are the dependencies:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>0.9.18</version>
</dependency>
(and add the commons-logging to the exclusion list, see here)
I struggled for a while to find SiftingAppender-like functionality in log4j (we couldn't switch to logback because of some dependencies), and ended up with a programmatic solution that works pretty well, using an MDC and appending loggers at runtime:
// this can be any thread-specific string
String processID = request.getProcessID();
Logger logger = Logger.getRootLogger();
// append a new file logger if no logger exists for this tag
if(logger.getAppender(processID) == null){
try{
String pattern = "%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n";
String logfile = "log/"+processID+".log";
FileAppender fileAppender = new FileAppender(
new PatternLayout(pattern), logfile, true);
fileAppender.setName(processID);
// add a filter so we can ignore any logs from other threads
fileAppender.addFilter(new ProcessIDFilter(processID));
logger.addAppender(fileAppender);
}catch(Exception e){
throw new RuntimeException(e);
}
}
// tag all child threads with this process-id so we can separate out log output
MDC.put("process-id", processID);
//whatever you want to do in the thread
LOG.info("This message will only end up in "+processID+".log!");
MDC.remove("process-id");
The filter appended above just checks for a specific process id:
public class RunIdFilter extends Filter {
private final String runId;
public RunIdFilter(String runId) {
this.runId = runId;
}
#Override
public int decide(LoggingEvent event) {
Object mdc = event.getMDC("run-id");
if (runId.equals(mdc)) {
return Filter.ACCEPT;
}
return Filter.DENY;
}
}
Hope this helps a bit.
I like to include all of the slf4j facades/re-routers/whateveryoucallthem. Also note the "provided" hack, which keeps dependencies from pulling in commons logging; previously I was using a fake empty commons logging library called version-99.0-does-not-exist.
Also see http://blog.springsource.com/2009/12/04/logging-dependencies-in-spring/
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<!-- use provided scope on real JCL instead -->
<!-- <version>99.0-does-not-exist</version> -->
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging-api</artifactId>
<!-- use provided scope on real JCL instead -->
<!-- <version>99.0-does-not-exist</version> -->
<version>1.1</version>
<scope>provided</scope>
</dependency>
<!-- the slf4j commons-logging replacement -->
<!-- if any package is using jakarta commons logging this will -->
<!-- re-route it through slf4j. -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${version.slf4j}</version>
</dependency>
<!-- the slf4j log4j replacement. -->
<!-- if any package is using log4j this will re-route -->
<!-- it through slf4j. -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${version.slf4j}</version>
</dependency>
<!-- the slf4j java.util.logging replacement. -->
<!-- if any package is using java.util.logging this will re-route -->
<!-- it through slf4j. -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${version.slf4j}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${version.slf4j}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${version.logback}</version>
</dependency>
</dependencies>
<properties>
<version.logback>0.9.15</version.logback>
<version.slf4j>1.5.8</version.slf4j>
</properties>
have you looked at log4j.NDC and MDC? This at least allows you to tag thread specific data to your logging. Not exactly what you're asking, but might be useful. There's a discussion here.

Resources