I have an incoming xml from Recurly service with list of transactions. Sometimes it's empty and looks like this:
<transactions type="array">
</transactions>
I need to deserialize this using Jackson. I've tried next mapping
#XmlRootElement(name = "transactions")
public class TransactionObjectListResponse extends ArrayList<TransactionObjectResponse> {
}
where TransactionObjectResponse class for each transaction. It works fine for non-empty collections, but fails when no transactions came. Next message appears:
java.lang.IllegalStateException: Missing name, in state: END_ARRAY
at com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser.getCurrentName(FromXmlParser.java:310)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:289)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:157)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:123)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:230)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:207)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
I used XmlMapper directly,
xmlMapper.readValue(responseXml, TransactionObjectListResponse.class);
Response entity structure isn't strict, any help would be appricated. Thanks.
I had a similar issue running the 2.2 version of "jackson-dataformat-xml". I took this one library down a version and it worked.
ie. (if you are using Maven)
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.2.3</version>
</dependency>
This is the same version as the 3rd party java recurly library uses - http://search.maven.org/#artifactdetails%7Ccom.ning.billing%7Crecurly-java-library%7C0.1.6%7Cjar
Related
I've got an integration flow written in the Java DSL
I'm enriching the header of a message to include an AtomicInteger:
.enrichHeaders(t -> t.headerFunction(pollTime,message -> new AtomicInteger()))
If I put a breakpoint on the subsequent handle method in the same flow I can see the header and it's a String not an AtomicInteger.
So if I try to retrieve it in another flow like so I get an illegal argument exception:
message.getHeaders().get(pollTime,AtomicInteger.class).getAndAdd(delay);
Caused by: java.lang.IllegalArgumentException: Incorrect type specified for header 'pollTime'. Expected [class java.util.concurrent.atomic.AtomicInteger] but actual type is [class java.lang.String]
If I do the same thing in the Kotlin DSL it all works fine:
enrichHeaders {
headerFunction<Any>(pollCount) {
AtomicInteger()
}
}
Does anyone have any idea of what I am doing wrong ?
I created a stand alone project to reproduce the error, and that added in the header as an expected AtomicInteger.
Then I debugged our main application and it turns out there's an OpenTracingChannelInterceptor which is re-writing all headers as Strings.
This library is the culprit:
io.opentracing.contrib:opentracing-spring-messaging:0.0.5 which is transitive dependency of io.opentracing.contrib:opentracing-spring-cloud-starter-jaeger
It looks like adding this library just breaks Spring Integration.
The fix is to exclude the tracing autoconfiguration:
#SpringBootApplication(exclude = {OpenTracingChannelInterceptorAutoConfiguration.class})
Update:
The opentracing library is now longer maintained so the long term fix for this would be to migrate to a different tracing library that hopefully doesn't have the same type of issue.
See
https://www.cncf.io/blog/2022/01/31/cncf-archives-the-opentracing-project/
I am using Infinispan alongside hibernate on my project and I encountered a strange error log:
ISPN000936: Class '[I' blocked by deserialization white list. Adjust the configuration serialization white list regular expression to include this class
I already have this issue but with normal class name so I could resolve the problem by adding the class to the serialization white-list like this:
globalConfigurationBuilder
.serialization()
.marshaller(new JavaSerializationMarshaller())
.whiteList()
.addClass(MyClass.class.getName());
but with this strange class name ('[I') I can't do this.
I can solve the problem by authorizing all the class in the serialization white-list like this :
globalConfigurationBuilder
.serialization()
.marshaller(new JavaSerializationMarshaller())
.whiteList()
.addRegexp(".*");
But I would like handle the problem in a more proper way.
Does someone have encountered the same issue and managed to solved it ?
[I is the internal name for an int[], so you can use any of the following:
.addClass("[I")
.addClass(int[].class.getName())
.addClasses(int[].class)
When you have more than one, I'd use the last one, which is a vararg method, e.g.
.addClasses(MyClass.class,
FooClass.class,
BarClass.class,
int[].class)
I am writing a RESTful service in java, but when I try using Resource class, the following error is shown: The type Response.Response builder is not visible. I don't understand what the problem might be, since I have already imported the needed jars and configured the classpath. Does anyone have an idea what might be causing the issue?
This is the method I am using to get a list of events, and I am getting the error wherever Response is used:
#GET
#Path("/active")
#Produces(MediaType.APPLICATION_JSON)
public Response getActiveEvents() {
ArrayList<Event> list = EventSetup.getActiveEvents();
if(list.size() > 0) return Response.status(200).entity(list).build();
else return Response.status(404).entity("NULL").build();
}
The code you listed is correct. As you specified JSON as output format, JAX-RS will serialize the result object (ArrayList<Event>) using an object mapper, usually Jackson.
I assume the error occured during serialization.
are there any custom or special serializers used (in the configuration of the ObjectMapper, or as Jackson annotations)? It's possible that one of these serializers make use of the Response builder, so they may be to blame.
did you import the correct Response class (javax.ws.rs.core.Response)? You might have accidentally imported a Response class from another package.
The stack trace is immensly helpful to locate the source of the Exception - please always include the stack trace when asking for help with exceptions you're getting.
I found the solution to this problem. All the jar files included in the project need to be in the WebContent/WEB-INF/lib folder, or Eclipse won't see them and will create an error.
I've been looking at the couchbase-java-client project and wondering whether it's possible to use it inside of a dropwizard project.
It seems like it'd be a natural fit, because couchbase is basically a JSON database, but the java client doesn't seem to be compatible with Jackson. As far as I can tell, the couchbase client library includes its own internal implementation of a JSON library that's incompatible with all the other java JSON libs out there, which is really weird.
I found a JacksonTransformers class that looked promising at first. But upon closer inspection, the library is using a shaded version of Jackson (with a rewritten package of com.couchbase.client.deps.com.fasterxml.jackson.core).
Anyhow, since dropwizard uses Jackson and Jersey for marshalling JSON documents through the REST API, what's the least-friction way of using the couchbase-java-client library? Is it even possible in this case?
It is definitely possible to use Couchbase with Dropwizard. The client SDK provides JSON manipulation objects for the developer's convenience but it also allows for delegating JSON processing to a library like Jackson or GSON.
Take a look at the RawJsonDocument class here.
Basically, you can use a Stringified JSON (coming out of any framework) to create one of those objects and the client SDK will understand it as a JSON document for any operation i.e.:
String content = "{\"hello\": \"couchbase\", \"active\": true}";
bucket.upsert(RawJsonDocument.create("rawJsonDoc", content));
It should be possible to make this work.
Client requests to dw server for Resource Person.
DW server requests to couchebase, gets a Pojo back representing Person or JSON representing person.
If it's JSON, create a POJO with Jackson annotations in DW and return that to client
If it's a special couchebase pojo, map that to a Jackson pojo and return to to client
A solution based on #CamiloCrespo answer:
public static Document<String> toDocument(String id, Object value,
ObjectMapper mapper) throws JsonProcessingException {
return RawJsonDocument.create(id, mapper.writeValueAsString(value));
}
Keep in mind, that you can't use a simply maper, like ObjectMapper mapper = new ObjectMapper(), with Dropwizard.
You can get it from Environment#getObjectMapper() in the Application#run() method, or use Jackson.newObjectMapper() for tests.
An example of using:
ObjectMapper mapper = Jackson.newObjectMapper();
User user = User.createByLoginAndName("login", "name");
bucket.insert(toDocument("123", user, mapper));
I'm using the last version at the moment of Firebase dependency, which is 1.0.2 and I'm having problems into getting my pojos parsed correctly.
The thing is, at any time the schema can changed but I don't want my app to crash with this:
D/AndroidRuntime(14097): Shutting down VM W/dalvikvm(14097):
threadid=1: thread exiting with uncaught exception (group=0x40a451f8)
E/AndroidRuntime(14097): FATAL EXCEPTION: main
E/AndroidRuntime(14097): com.firebase.client.FirebaseException: Failed
to bounce to type E/AndroidRuntime(14097): at
com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:213)
Looking into the dependency tree I get that Firebase is using Jackson mapper 1.9.7, so the annotation #JsonIgnoreProperties(ignoreUnknown = true") is not an option. Moreover, the object mapper is wrapped into this Firebase object so I can't configure the DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES property (DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES for Jackson 1.9 and before).
Is there any way to set this property, either as a class-level annotation or configuring the mapper or any other mechanism whatsoever?
The best solution would be that Firebase 1.0.3 started using Jackson 2.0, but don't know if this is something they care about right now.
Note: I've already thought about excluding the transitive Jackson 1.9.7 dependency and adding Jackson 2.0 so that I can access to this ignoreUnknown feature, but I don't think it is a viable choice since I would be changing the mayor version.
For those who have moved over to Google's official version of Firebase (As of May 29, 2016), you can use #Exclude instead of #JsonIgnore or #JsonProperty. Here is the link to their document.
Example:
public class dataPacket{
public String data;
...
#Exclude
public String getData(){return data;}
}
Update:
As others pointed, annotation #Exclude is right way to use it now. But if you use Kotlin that won't work. For Kotlin use
#Exclude #JvmField
var data: String? = nil
//or
#set:Exclude #get:Exclude
var data: String? = nil
Because annotation can be applied only for generated fields and not to properties.
Old answer:
I'm coming to Firebase from GSON were I used transient keyword. And that works with Firebase too
public transient String data;
As the accepted answer states, Firebase now uses Jackson, so you can annotate the desired methods you wish to ignore with
#JsonIgnore
Edit:
Firebase changed everything. Woot. Now use this instead:
#Exclude
Firebase 1.0.3 was released and now uses Jackson 2.2.2, so annotation #JsonIgnore is the way to go.
Edit:
as of now in 2017, Firebase doesn't use Jackson anymore. the correct annotation is #Exclude.