Is there a way to throw user defined exception in XmlAdapter and catch them when JAXB marshalles/unmarshalls? I mean, I can throw my own exception but JAXB just ignores this exception and throws his own from which I can not get to my exception message or the exception object.
try {
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
jaxbUnmarshaller.unmarshal(inputStream);
}
catch (UserDefinedException e) {
// Do something.
}
Sorry for not posting the correct exception that JAXB throwed instead of mine. At this moment, I can not get to the code. Currentlly I am using JAXB-RI, but I used EclipseLink MoXY and encountered this problem.
I will post additional data when I am able to get the hand of the code. But till then, maybe someone knows what am I talking about. Some code example of correct usage of XmlAdapter is also great.
Thanks.
The expectation of a JAXB (JSR-222) implementation is that it throws a JAXBException. This means that any exceptions thrown within something like an XmlAdapter is going to end up getting wrapped. You could potentially use a stateful XmlAdapter to handle this use case:
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
MyXmlAdpater myXmlAdapter = new MyXmlAdapter();
jaxbUnmarshaller.setAdatper(myXmlAdapter);
jaxbUnmarshaller.unmarshal(inputStream);
if(myXmlAdapter.hasException() {
// Do something.
}
For an Example of using a stateful XmlAdapter see:
http://blog.bdoughan.com/2011/09/mixing-nesting-and-references-with.html
Related
How to handle nested transactions in spring integration flow. Basically i have a process that fetches all the orders from database and process it order by order, in case of exception thrown on single order, all the orders processed are getting rolled back.
IntegrationFlows.from("perOrder")
.filter(Order.class, order -> order.getItems().size() > 0)
.handle(orderHandler, "handle") /*someway i way want to add try/catch for this method here so that
if handle method throws exception, want to suppress for that order and mark as failure only for that order */
.get();
public class OrderHandler {
#Transactional(propagation = Propagation.NESTED)
public handle() {
processing code
throw exception in case of any validation failure
}
}
For this purpose we provide an adviceChain to be injected into the endpoint of that handle():
.handle((GenericHandler<?>) (p, h) -> {
throw new RuntimeException("intentional");
}, e -> e.advice(retryAdvice()))
You can inject there any available Advice implementation: https://docs.spring.io/spring-integration/docs/current/reference/html/#message-handler-advice-chain, including TransactionInterceptor: https://docs.spring.io/spring-integration/docs/current/reference/html/#tx-handle-message-advice
The best way to have a try...catch semantics is with the ExpressionEvaluatingRequestHandlerAdvice. See its description in the Docs and also its JavaDocs.
Is there mongodb mapping converter for generic message.
No argument constructor not available for generic message.
.11:47:30.937 [http-nio-9080-exec-1] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.messaging.MessageHandlingException: error occurred in message handler [messageHandler]; nested exception is org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate org.springframework.messaging.support.GenericMessage using constructor NO_CONSTRUCTOR with arguments ] with root cause
java.lang.NoSuchMethodException: org.springframework.messaging.support.GenericMessage.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:104)
at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:61)
at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:83)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:251)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:231)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1186)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.access$200(MappingMongoConverter.java:78)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1134)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1097)
Also I am trying following config of mongotemplate
Please advise if correct
public MongoTemplate messagingMongoTemplate() throws Exception {
MongoTemplate mongoTemplate=null;
try {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
MappingContext mappingContext = new MongoMappingContext();
MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver,mappingContext);
CustomConversions customConversions = new CustomConversions(Arrays.asList(new MongoDbMessageBytesConverter()));
mappingMongoConverter.setCustomConversions(customConversions);
mongoTemplate=new MongoTemplate(mongoDbFactory,mappingMongoConverter);
Starting with version 3.0 it is recommended to use ConfigurableMongoDbMessageStore as that provides more options for customization, including a Converter for Message.
Out-of-the-box Spring Integration provides MongoDbMessageBytesConverter, which has become public since 4.2.10 and is used by default if there is no any external customization for the ConfigurableMongoDbMessageStore.
I just received an exception when I try to reference a static variable in another class, which is also statically initialized. This worked before, and for some reason it fails now. The only changes I made were resetting Visual Studio (2010) to its default setting, which I can't imagine to be the reason for this. Any other code I added didn't touch any of the affected parts either.
This is my code
WinForms class 'MainForm':
partial class MainForm : Form
{
// ...
private RefClass convMan;
private Dictionary<EnumType, string> LogNames = RefClass.LogNames;
// ...
public MainForm() { .... }
}
Referenced class 'RefClass':
class RefClass
{
// ...
public enum EnumType { TypeOne = 0, TypeTwo = 1, TypeThree = 2 };
public static Dictionary<EnumType, string> LogNames = new Dictionary<EnumType, string>()
{
{ EnumType.TypeOne, "Text0" },
{ EnumType.TypeTwo, "Text1" },
{ EnumTypy.TypeThree, "Text2" }
};
}
The error I get now is (translated from German):
An unhandled exception of type "System.TypeInitializationException" occurred.
Additional information: The type initializer for "RefClass" threw an exception.
which has the InnerException
System.ArgumentException
So, as far as I'm concerned, my static dictionary should be initialized once it gets accessed, thus when my Form class references it. I tried debugging to see if the static dictionary is initialized before it gets referenced in the Form class, which is not the case. Also, when I stop at a breakpoint for the reference line, the variable LogNames is null.
I'm really confused as to why this happens, it all worked before.
I found my error, the exceptions I got were quite misleading though. It was a problem with a different dictionary than the one I referenced. It probably didn't get initialized in the first place because something before that failed (If someone can clear this up, please feel free to do so!). Basically what I did wrong was using a two-directional dictionary and adding a value twice. This should normally produce a normal exception, but since it was done statically it got wrapped into a TypeInitializationException. I had a deeper look into the exact stacktrace of the inner exception and found where the exception originated from. Maybe this helps someone in the future...
I had a simular issue getting the same exception. Found that my static constructor for my utility class was generating the exception. Took some time locating since the description of the exception was misleading.
As #Yeehaw mentioned, it appears that the exception gets wrapped, so the common denominator here I would say is that the class/object is static.
EDIT #1: I used JAXB RI 2.2.6 (latest as of today 12/06/12), and I
observe the same behavior :-(
I am using JAXB for unmarshalling XML payloads.
When I pass an invalid payload for the first time via Unmarshaller, I get the following type of error:
javax.xml.bind.UnmarshalException: Unable to create an instance of foo.bar.FooBarType
- with linked exception:
[java.lang.InstantiationException]
On the next line in my code (in the catch() block), I try the same Unmarshaller instance and give a valid payload, where I get following type of error:
java.lang.ClassCastException: foo.bar.SomeAType cannot be cast to foo.bar.SomeBType
On the next line (again in the subsequent catch()), I try the same Unmarshaller instance and again give the same valid payload, which unmarshals fine!
Has anyone experienced this kind of behavior with JAXB? Am I hitting a bug here? Where to look/dig?
Here are the details of the manifest of JAXB jar that I am using:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 1.5.0_12-b04 (Sun Microsystems Inc.)
Specification-Title: Java Architecture for XML Binding
Specification-Version: 2.1
Specification-Vendor: Sun Microsystems, Inc.
Implementation-Title: JAXB Reference Implementation
Implementation-Version: 2.1.12
Implementation-Vendor: Sun Microsystems, Inc.
Implementation-Vendor-Id: com.sun
Extension-Name: com.sun.xml.bind
Build-Id: hudson-jaxb-ri-2.1-833
Class-Path: jaxb-api.jar activation.jar jsr173_1.0_api.jar jaxb1-impl.jar
Name: com.sun.xml.bind.v2.runtime
Implementation-Version: hudson-jaxb-ri-2.1-833
Thank you much in advance!
EDIT #2: It's not possible to paste everything, but here's the gist of what it is looking like:
final JAXBContext jaxbContext = JAXBContext.newInstance(FooRequestType.class);
final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement<FooRequestType> result = null;
try {
//try unmarshalling invalid payload.
result = unmarshaller.unmarshal(invalidPayload.getDocumentElement(), FooRequestType.class);
}catch(Exception e1){
try {
//now try unmarshalling valid payload . ##NOTE: If you try unmarshalling Invalid Payload here, it will fail again.
result = unmarshaller.unmarshal(validPayload.getDocumentElement(), FooRequestType.class);
} catch(Exception e2){
//try again unmarshalling valid payload
result = unmarshaller.unmarshal(validPayload.getDocumentElement(), FooRequestType.class);
System.out.println("Result:=" + result.getValue());
System.out.println("Successfully unmarshalled. Exiting with (0)");
System.exit(0);
}
}
System.out.println("Not expecting to reach here.Exiting with (1)");
System.exit(1);
EDIT #3: Ran the same piece of code by using EclipseLink MOXy as the JAXB Impl; and it behaves correctly.
I opened a bug on Sun/Oracle JAXB RI: http://java.net/jira/browse/JAXB-931
I've a JSON something like this:
objects:[{
id:"p452365",
type:"photo",
link:"http://xxx.zz"
},
{
id:"v7833",
type:"video",
link:"http://xxx.yy",
length:"4.12"
}
]
In superclass Entity, there're 2 instance variables: id and type. In my extended XmlAdapter class I tried to cast my Entity instances to a subtype for ex. Photo
public HashMap<String, List<Column>> unmarshal(Feeds f) throws Exception {
for(Feed feed : f.getFeeds()){
System.out.println("Entity id for feed : " + feed.getId());
for(Entity e:feed.getObjects()){
if (e instanceof Photo){
// Of course it's not
}
}
}
return (HashMap<String, List<Column>>)fm.map(f.getFeeds());
}
Of course e isn't an instanceof Photo, I took a shot there.:)
What I wanna do is to interfere the JAXB process sometime and unmarshall according to the type value in JSON.I wonder where and how.
One of my previous answers to a similar question may help here. Essentially it is using the #XmlDescrimatorNode in EclipseLink JAXB (MOXy). Note I'm the MOXy tech lead.
Java/JAXB: Unmarshall Xml to specific subclass based on an attribute
You could also do this with an XmlAdapter. AdaptedEntity would have all the properties from Entity and it's subclasses.
JAXB #XmlElements, different types but same name?