Resteasy with wildfly14: not all fields are returned - serialization

I'm migrating my application from wildfly 10 to wildfly 14 and I'm using resteasy 3.1.4 with jackson2.
I have a strange behaviour with the response of some rest services: not all the fields are returned (and I'm sure they're extracted from mongodb). The only warning I see when deploying my application is:
WFLYRS0018: Explicit usage of Jackson annotation in a JAX-RS deployment; the system will disable JSON-B processing for the current deployment. Consider setting the 'resteasy.preferJacksonOverJsonB' property to 'false' to restore JSON-B.
In the response I have two classes:
public class Field implements Serializable {
private static final long serialVersionUID = -230381150649916138L;
private String name; // returned in response
private FieldsTypeEnum type; // NOT returned in response
private List<String> comboValues; // NOT returned in response
private boolean required; // NOT returned in response
//All getters and setters
}
public class ConfigurationField extends Field {
private static final long serialVersionUID = -2727277793405725817L;
private Integer row; // returned in response
private boolean useForCalendar; // returned in response
//All getters and setters
}
Any help or suggest or idea is really appreciated
Thanks

It has been 6 months since the question was asked. However, I faced the similar issue a few days ago on Wildfly 16.
The issue was caused by JsonBindingProvider takes precedence over the other providers for dealing with JSON payloads, particular the Jackson one.
https://issues.jboss.org/browse/RESTEASY-1911
Please see documentation here.
https://github.com/resteasy/Resteasy/commit/f6ddef5accb88d924e3d14ab15e081c79136fe55
It can be fixed by 2 ways without having to update your model (POJO) objects:
Adding system property when starting up Wildfly -Dresteasy.preferJacksonOverJsonB=true
Exclude jsonb module in jboss-deployment-structure.xml
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
<deployment>
<exclusions>
<module name="org.jboss.resteasy.resteasy-json-binding-provider" />
</exclusions>
</deployment>
</jboss-deployment-structure>
If you do not want to change Wildfly configuration, you have to update you models to conform with JsonB specification, e.g. public your private fields in your models, or adding suitable #Jsonb annotations to your fields, ... like here, https://www.baeldung.com/java-json-binding-api.

Based on the answer from Soner, this helped me when added to web.xml:
<context-param>
<param-name>resteasy.preferJacksonOverJsonB</param-name>
<param-value>true</param-value>
</context-param>
I prefer this solution in order to keep the configuration within the app code.

I had similar problems within Wildfly 21. Adding a jboss-deployment-structure.xml like:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.3">
<deployment>
<exclusions>
<module name="org.jboss.resteasy.resteasy-json-binding-provider"/>
</exclusions>
<dependencies>
<module name="org.jboss.resteasy.resteasy-jackson2-provider" />
</dependencies>
</deployment>
</jboss-deployment-structure>
didn't help
For me the working solution was to add following line into the Wildfly standalone.conf to prefer jackson:
JAVA_OPTS="$JAVA_OPTS -Dresteasy.preferJacksonOverJsonB=true"

Related

How to make EclipseLink MOXy ignore AspectJ fields?

How do I make a bytecode-only Field be #XmlTransient?
When a class is woven by AspectJ, its bytecode (but not its source code) receives an extra injected static field:
private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0;
This extra field is not treated as XmlTransient by MOXy, and causes an Exception when trying to create a JAXBContext:
Caused by: javax.xml.bind.JAXBException:
Exception Description: The class org.aspectj.runtime.reflect.JoinPointImpl$StaticPartImpl requires a zero argument constructor or a specified factory method. Note that non-static inner classes do not have zero argument constructors and are not supported.
- with linked exception:
[Exception [EclipseLink-50001] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The class org.aspectj.runtime.reflect.JoinPointImpl$StaticPartImpl requires a zero argument constructor or a specified factory method. Note that non-static inner classes do not have zero argument constructors and are not supported.]
Possible solutions
According to the EclipseLink MOXy example, it seems that I should be able to make this field #XmlTransient by creating a file called eclipselink-oxm.xml with the content below, and place the file within the directory src/main/resources/META-INF. However, this does not work.
How should I proceed here?
eclipselink-oxm.xml
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="${eclipselink.version}">
<java-types>
<java-type name="se.mithlond.services.organisation.model.address.CategorizedAddress">
<java-attributes>
<xml-transient java-attribute="ajc$tjp_0"/>
</java-attributes>
</java-type>
<!--java-type name="org.aspectj.runtime.reflect.JoinPointImpl$StaticPartImpl" xml-transient="true" />
<java-type name="org.aspectj.runtime.reflect.JoinPointImpl" xml-transient="true" / -->
</java-types>
</xml-bindings>

EclipseLink MOXy #XmlPath is returning the incorrect data for contains

I am attempting to unmarshal an XML data stream with EclipseLink MOXy with an XPath using the contains function.
When I apply the sample XPath directly to the sample XML data stream I get the correct value returned (Ref_number_1). However, when I unmarshal this using MOXy, the value that is set for refNumber1 is "Ref_number_2".
Does MOXy not support this type of XPath? It would appear that it at least is understanding it because it's not throwing an error, just setting the wrong value.
Anyone have any experience with this sort of thing? Know of a better approach?
Thanks for any help.
Marshal code:
String s = //xml stream from restful service (see xml example below);
StringReader sr = new StringReader(s);
ReferenceNumber refNum = (ReferenceNumber)marshaller.unmarshal(
new StreamSource(sr));
Member annotation:
#XmlPath("Header/ReferenceNumbers/ReferenceNumber[contains(ReferenceNumberType, \"REF_NUMBER_TYPE_1\")]/ReferenceNumber/text()")
private String refNumber1;
XML data:
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<Header>
<ReferenceNumbers>
<ReferenceNumber>
<ReferenceNumber>Ref_number_1</ReferenceNumber>
<ReferenceNumberType>REF_NUMBER_TYPE_1</ReferenceNumberType>
</ReferenceNumber>
<ReferenceNumber>
<ReferenceNumber>Ref_number_2</ReferenceNumber>
<ReferenceNumberType>REF_NUMBER_TYPE_2</ReferenceNumberType>
</ReferenceNumber>
</ReferenceNumbers>
</Header>
</Document>
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
Currently MOXy does not support XPaths of that form. Currently a conditional check must be on an attribute contained within the element such as (see: http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.html).
#XmlPath("personal-info/name[#type='first']/text()")
String firstName;
I have entered the following bug so that we improve the validation that we do on our #XmlPath annotation:
http://bugs.eclipse.org/397101
I am also interested in the use case described in your question. Would you mind entering an enhancement requires against the MOXy component for this:
https://bugs.eclipse.org/bugs/enter_bug.cgi?product=EclipseLink

Jackrabbit - why does search excerpt contain all node properties concatenated?

When I perform a jackrabbit (version 2.2.9) search and I call get row.getValue("rep:excerpt()") the returned string is just all the properties (excluding jcr: properties) concatenated. How do I control this? eg. If I have a property called "description" containing "bla foo bla" when I search for "foo" I would like to see rep:excerpt() return part of just the description.
I tried creating an index config (and I deleted my repository between tests) in an attempt to control what properties were indexed, to no avail.
Workspace.xml...
<SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
<param name="path" value="${wsp.home}/index"/>
<param name="supportHighlighting" value="true"/>
<param name="excerptProviderClass" value="org.apache.jackrabbit.core.query.lucene.DefaultHTMLExcerpt"/>
<param name="indexingConfiguration" value="${wsp.home}/indexing_configuration.xml"/>
</SearchIndex>
indexing_configuration.xml
<?xml version="1.0"?>
<!DOCTYPE configuration SYSTEM "http://jackrabbit.apache.org/dtd/indexing-configuration-1.0.dtd">
<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
<index-rule nodeType="nt:teneoNode">
<property>description</property>
<property>input</property>
<property>key</property>
<property>comment</property>
</index-rule>
</configuration>
Thanks.
Ted.
You can configure the ExcerptProvider (Javadoc) implementation which is responsible for the rep:excerpt() functionality in the SearchIndex element of you workspace.xml file:
<param name="excerptProviderClass" value="org.apache.jackrabbit.core.query.lucene.DefaultHTMLExcerpt"/>
You might need to plugin in your own implementation for you specific needs.
There is also some - unfortunately rather old - information on the Jackrabbit Wiki.

Problem with struts 2 and json plugin

I'm using the json plugin that comes with struts 2 (json-lib-2.1.jar) and trying to follow the website to set it up.
Here's my struts.xml
<struts>
<package name="example" extends="json-default">
<action name="AjaxRetrieveUser" class="actions.view.RetrieveUser">
<result type="json"/>
</action>
</package>
</struts>
but I get this warning:
SEVERE: Unable to find parent packages json-default
Is there something else I'm supposed to do?
Edit:
I added this method to my RetrieveUser:
public Map<String,Object> getJsonModel()
{
return jsonModel;
}
And my struts.xml looks like this:
<struts>
<package name="example" extends="json-default">
<action name="AjaxRetrieveUser" class="actions.view.RetrieveUser">
<result type="json"/>
<param name="root">jsonModel</param>
</action>
</package>
</struts>
However, I don't think the response is going from the RetrieveUser class to the javascript. I'm using firebug and no request gets sent.
I believe that net.sf.json-lib is just a toolset you can use in your Java to build up JSON-ready objects, suitable to be returned by actions such as you describe.
Probably, you need to include struts-json-plugin - make sure its version matches your struts version.
I notice also that as written, your action will attempt to return RetrieveUser, serialized. Most implementations I've done/seen specify the root object to be returned, by adding
<param name="root">jsonUser</param>
Under the tag, and define this method in RetrieveUser
public Map<String, Object> getJsonUser()
[This is mentioned in the Sruts2 doc]. Hope that helps.
[edit] I use Map - you could also use the object structures provided by json-lib instead.
Re: Your edit. Probably need to see your calling javascript. And probably I will suggest that you make sure you have both a success and an error handler. Can you debug/log to show that the method is being called in java ? Do your logs show anything ? This is usually some sort of error....

Simulating the Maven2 filter mechanism using Ant

I have a properties file, let say my-file.properties.
In addition to that, I have several configuration files for my application where some information must be filled regarding the content of my-file.properties file.
my-file.properties:
application.version=1.0
application.build=42
user.name=foo
user.password=bar
Thus, in my configuration files, I will find some ${application.version}, ${user.name} that will be replaced by their value taken in the properties file...
When I build my application using Maven2, I only need to specify the properties file and say that my resources files are filtered (as in this answer to another problem). However, I need to achieve the same thing by using only Ant.
I've seen that Ant offers a filter task. However, it forces me to use the pattern #property.key# (i.e. #user.name# instead of #{user.name}) in my configuration files, which is not acceptable in my case.
How can I solve my problem?
I think expandproperties is what you are looking for. This acts just like Maven2's resource filters.
INPUT
For instance, if you have src directory (one of many files):
<link href="${css.files.remote}/css1.css"/>
src/test.txt
PROCESS
And in my ANT build file we have this:
<project default="default">
<!-- The remote location of any CSS files -->
<property name="css.files.remote" value="/css/theCSSFiles" />
...
<target name="ExpandPropertiesTest">
<mkdir dir="./filtered"/>
<copy todir="./filtered">
<filterchain>
<expandproperties/>
</filterchain>
<fileset dir="./src" />
</copy>
</target>
</project>
build.xml
OUTPUT
*When you run the ExpandPropertiesTest target you will have the following in your filtered directory: *
<link href="/css/theCSSFiles/css1.css"/>
filtered/test.txt
You can define a custom FilterReader. So you have a couple of choices:
Extend/copy the org.apache.tools.ant.filters.ReplaceTokens class and define a Map property that references another properties file containing all the replacements. This is still a bit of a chore as you have to define all the replacements.
Extend/copy the org.apache.tools.ant.filters.ReplaceTokens class with additional processing that just substitutes the matched token with a version with the correct garnish. Of course you'd have to be really careful where you use this type as it will match anything with the begin and end token.
So in the read() method of ReplaceTokens, replace:
final String replaceWith = (String) hash.get(key.toString());
with a call to a getReplacement() method:
...
final String replaceWith = getReplacement(key.toString);
...
private String getReplacement(String key) {
//first check if we have a replacement defined
if(has.containsKey(key)) {
return (String)hash.get(key);
}
//now use our built in rule, use a StringBuilder if you want to be tidy
return "$" + key + "}";
}
To use this, you'd ensure your class is packaged and on Ant's path and modify your filter:
<filterreader classname="my.custom.filters.ReplaceTokens">
<!-- Define the begin and end tokens -->
<param type="tokenchar" name="begintoken" value="$"/>
<param type="tokenchar" name="endtoken" value="}"/>
<!--Can still define explicit tokens, any not
defined explicitly will be replaced by the generic rule -->
</filterreader>
One hooooooorible way to make this work, inspired by the solution of Mnementh, is with the following code:
<!-- Read the property file -->
<property file="my-file.properties"/>
<copy todir="${dist-files}" overwrite="true">
<fileset dir="${src-files}">
<include name="*.properties"/>
</fileset>
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
<!-- Define the begin and end tokens -->
<param type="tokenchar" name="begintoken" value="$"/>
<param type="tokenchar" name="endtoken" value="}"/>
<!-- Define one token per entry in the my-file.properties. Arggh -->
<param type="token" name="{application.version" value="${application.version}"/>
<param type="token" name="{user.name" value="${user.name}"/>
...
</filterreader>
</filterchain>
</copy>
Explanations:
I am using the ReplaceTokens reader to look for all $...} pattern. I cannot search for ${...} patterns, as the begintoken is a char and not a String. Then, I set the list of tokens starting with a { (i.e. I see {user.name instead of user.name). Hopefully, I have "only" about 20 lines in my-file.properties, so I need to define "only" 20 tokens in my Ant file...
Is there any simple and stupid solution to solve this simple and stupid problem??
Ant knows a concept named Filterchains, that is useful here. Use the ReplaceTokens-filter and specify the begintoken and endtoken as empty (normally that's '#'). That should do the trick.