org.apache.camel.InvalidPayloadException: No body available of type error thrown while unMarshalling Jaxb Object - jaxb

I am sending JAXB Object to Rabbit MQ via Java.
JAXBContext jaxbContext = JAXBContext.newInstance(MyDTO.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
java.io.StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(deliveryrequest, sw);
ConnectionFactory factory = new ConnectionFactory() ;
//TODO change the hardcoding to the properties file
factory.setHost("rabbitmq.host.net");
factory.setUsername("user");
factory.setPassword("pass");
Channel channel ;
Connection connection;
Map<String, Object> args = new HashMap<String, Object>();
String haPolicyValue = "all";
args.put("x-ha-policy", haPolicyValue);
connection = factory.newConnection();
channel = connection.createChannel();
//TODO change the hardcoding to the properties file
channel.queueDeclare("upload.com.some.queue", true, false, false, args);
//TODO change the hardcoding to the properties file
channel.basicPublish("com.some.exchange", "someroutingKey",
new AMQP.BasicProperties.Builder().contentType("text/plain")
.deliveryMode(2).priority(1).userId("guest").build(),
sw.toString().getBytes());
I am using Camel in different application to read this.
<camel:route id="myRoute">
<camel:from uri="RabbitMQEndpoint" />
<camel:to uri="bean:MyHandler" />
</camel:route>
Handler is using the Jaxb object redone in camel side
#Handler
public void handleRequest(MyDTO dto) throws ParseException {
I am getting the error which I did not expect to get.
Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: byte[] to the required type: com.mycompany.MyDTO with value [B#1b8d3e42
at org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:181)
at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:99)
Solution is appreciated.

Your message body type from rabbit is a byte[], and you want to call a bean which as MyDTO type. You have a type mismatch. And Camel cannot find a type converter that can convert the message body from byte[] to your MyDTO type.
Is the byte[] data from Rabbit in XML format? And do you have JAXB annotations on MyDTO classes, so you could use JAXB to marshal that from xml to Java ?

It is Jaxb object. I was under impression that if i move the publisher too Camel. Things will be sorted out.
I changed the publisher to the following.
#EndpointInject(context = "myContext" , uri = "direct:myRoute")
private ProducerTemplate sendAMyContext;
And in method I called
#Override
public MyResponse putMyCall(
MyRequest myrequest) {
sendMyContext.sendBody(myrequest);
My camel route is simple one
<camel:camelContext id="MyContext" autoStartup="true" xmlns="http://camel.apache.org/schema/spring">
<camel:endpoint id="myQueue" uri="${my.queue.1}" />
<camel:route>
<camel:from uri="direct:myRoute"/>
<camel:to uri="bean:mySendHandler"/>
<camel:convertBodyTo type="String"></camel:convertBodyTo>
<camel:to uri="ref:myQueue" />
</camel:route>
</camel:camelContext>
I added the handler to convert the Jaxb object to string(because of error)
public class MySendHandler {
#Handler
public String myDelivery( MyRequest myRequest) throws ParseException, JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(MyRequest.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
java.io.StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(attributedDeliveryRequest, sw);
return sw.toString();
}
Still the same error
[SpringAMQPConsumer.SpringAMQPExecutor-1] WARN org.springframework.amqp.support.converter.JsonMessageConverter (JsonMessageConverter.java:111) - Could not convert incoming message with content-type [text/plain]
SpringAMQPConsumer.SpringAMQPExecutor-1] ERROR org.apache.camel.processor.DefaultErrorHandler (MarkerIgnoringBase.java:161) - Failed delivery for (MessageId: ID-Con ExchangeId: ID-65455-1380873539452-3-2).
Exhausted after delivery attempt: 1 caught: org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[Message: <XML>]
org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[Message: <xml>
.....
Caused by: org.apache.camel.InvalidPayloadException: No body available of type: MyDTO but has value: [B#7da255c of type: byte[] on: Message: <xml>
. Caused by: [org.apache.camel.NoTypeConversionAvailableException - No type converter available to convert from type: byte[] to the required type: MyDeliveryDTO with value [B#7da255c]
at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:101)
at org.apache.camel.builder.ExpressionBuilder$38.evaluate(ExpressionBuilder.java:934)
... 74 more
Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: byte[] to the required type: MyDTO with value [B#7da255c
at org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:181)
at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:99)
... 75 more
My receiving camel route is as below
<camel:route id="processVDelivery">
<camel:from uri="aVEndpoint" />
<camel:to uri="bean:myDataHandler" />
</camel:route>
I added
<camel:convertBodyTo type="String"></camel:convertBodyTo>
to it and it gave me error that it cannot convert it from string to the object
adding this
<camel:unmarshal></camel:unmarshal>
-------------------------
Answer to the question will be all your mashaller have to be part of classpath
---------------------------------
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>${jackson.version}</version>
</dependency>
------- Also you can the custom marshaller using dataformat
<camel:dataFormats>
<camel:jaxb id="name" contextPath="com.something"/>
</camel:dataFormats
make sure that you keep jaxb.index file in com.something package with the root level Jaxb object name

Using Camel Rest with Spring boot
rest("/authenticate")
.post()
.route()
.setHeader("Content-Type", constant("application/json"))
.setHeader("Accept", constant("application/json"))
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.process(exchange -> {
org.apache.camel.TypeConverter tc = exchange.getContext().getTypeConverter();
String str_value = tc.convertTo(String.class, exchange.getIn().getBody());
System.err.println(str_value);
exchange.getOut().setBody(str_value);
})
//.removeHeader(Exchange.HTTP_URI)
.to("http://localhost:8082/authenticate?bridgeEndpoint=true")
//.convertBodyTo(DTO.class)
.log("Boo!")
.end()
.endRest();

Related

Message history not getting deserialized

I was trying to send message history via kafka backed message channel, and i am getting an error like below:
Caused by: java.lang.IllegalArgumentException: Incorrect type specified for header 'history'. Expected [class org.springframework.integration.history.MessageHistory] but actual type is [class org.springframework.kafka.support.DefaultKafkaHeaderMapper$NonTrustedHeaderType]
at org.springframework.messaging.MessageHeaders.get(MessageHeaders.java:216)
at org.springframework.integration.history.MessageHistory.write(MessageHistory.java:96)
Environment:
Java version: JDK8
Kafka version: 3.1.0
Spring-boot-starter-integration: 2.6.2 (integration core:5.5.7)
The message is getting deserialized properly without message history, but unable to do so with message history.
Here is the configuration that I am setting:
Consumer:
public ConsumerFactory consumerFactory(String groupId, String clientId) {
Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, AUTO_OFFSET_RESET_CONFIG);
consumerProperties
.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
consumerProperties.put(ConsumerConfig.CLIENT_ID_CONFIG, clientId);
consumerProperties.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG,MAX_POLL_INTERVAL_MS_CONFIG);
consumerProperties.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG,MAX_POLL_RECORDS_CONFIG);
DefaultKafkaConsumerFactory defaultKafkaConsumerFactory = new DefaultKafkaConsumerFactory(
consumerProperties);
JsonDeserializer jsonDeserializer = new JsonDeserializer(GenericMessage.class, JacksonJsonUtils.messagingAwareMapper());
jsonDeserializer.addTrustedPackages("*");
defaultKafkaConsumerFactory.setValueDeserializer(jsonDeserializer);
return defaultKafkaConsumerFactory;
}
Producer:
public ProducerFactory<String, String> producerFactory() {
Map<String, Object> producerConfigMap = new HashMap<>();
producerConfigMap.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
producerConfigMap.put(ProducerConfig.LINGER_MS_CONFIG, PRODUCER_LINGER_MS_CONFIG);
producerConfigMap.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, PRODUCER_COMPRESSION_TYPE_CONFIG);
producerConfigMap.put(ProducerConfig.BATCH_SIZE_CONFIG, PRODUCER_BATCH_SIZE_CONFIG);
producerConfigMap
.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
JsonSerializer<GenericMessage> jsonSerializer = new JsonSerializer(JacksonJsonUtils.messagingAwareMapper());
DefaultKafkaProducerFactory defaultKafkaProducerFactory = new DefaultKafkaProducerFactory<>(
producerConfigMap);
defaultKafkaProducerFactory.setValueSerializer(jsonSerializer);
return defaultKafkaProducerFactory;
}
ConcurentKafkaContainerListenerFactory:
public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory(
String groupId, String clientId) {
DefaultKafkaHeaderMapper kafkaHeaderMapper = new DefaultKafkaHeaderMapper();
kafkaHeaderMapper.addTrustedPackages("org.springframework.integration.history");
MessagingMessageConverter messagingMessageConverter = new MessagingMessageConverter();
messagingMessageConverter.setHeaderMapper(kafkaHeaderMapper);
ConcurrentKafkaListenerContainerFactory<String, String> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory(groupId, clientId));
factory.setMessageConverter(messagingMessageConverter);
return factory;
}
I have tried adding trusted packages in every possible way, but still, I am getting the above error.
Looks at the exception again: org.springframework.kafka.support.DefaultKafkaHeaderMapper$NonTrustedHeaderType. It doesn't say that something is wrong with your (de)serializers. It is a DefaultKafkaHeaderMapper mapper feature to ban that type from you.
You need to supply a DefaultKafkaHeaderMapper with the addTrustedPackages("*") on the consumer side. If you use KafkaMessageDrivenChannelAdapter, see its setMessageConverter(MessageConverter messageConverter) to be populated with the MessagingMessageConverter. And that one has an option for the setHeaderMapper(KafkaHeaderMapper headerMapper), where you already can set that DefaultKafkaHeaderMapper.
Please, raise a GH, so we can add that org.springframework.integration.history to trusted packages for a default DefaultKafkaHeaderMapper in the KafkaMessageDrivenChannelAdapter.

MOXy: Efficient deep copy of JAXBElement

docx4j v3.3.0 uses the following code to clone a JAXB object:
public static <T> T deepCopy(T value, JAXBContext jc) {
if (value==null) {
throw new IllegalArgumentException("Can't clone a null argument");
}
try {
#SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>) value.getClass();
JAXBElement<T> contentObject = new JAXBElement<T>(new QName(clazz.getSimpleName()), clazz, value);
JAXBSource source = new JAXBSource(jc, contentObject);
JAXBElement<T> elem = jc.createUnmarshaller().unmarshal(source, clazz);
T res;
if (value instanceof JAXBElement<?>) {
#SuppressWarnings("unchecked")
T resT = (T) elem;
res = resT;
} else {
#SuppressWarnings("unchecked")
T resT = (T) elem.getValue();
res = resT;
}
return res;
} catch (JAXBException ex) {
throw new IllegalArgumentException(ex);
}
}
With MOXy v2.5.2 (which we use, since it supports Java 6) and the latest 2.6.3, attempting to clone a JAXBElement, for example:
public void testIssue212() {
CTBookmark bookmark = Context.getWmlObjectFactory().createCTBookmark();
JAXBElement<CTBookmark> el =Context.getWmlObjectFactory().createBodyBookmarkStart(bookmark);
Object o = XmlUtils.deepCopy(el);
}
results in:
[Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class javax.xml.bind.JAXBElement was not found in the project. For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.]
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.handleXMLMarshalException(JAXBUnmarshaller.java:980)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:303)
at org.docx4j.XmlUtils.deepCopy(XmlUtils.java:974)
... 25 more
Caused by: Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class javax.xml.bind.JAXBElement was not found in the project. For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.
at org.eclipse.persistence.exceptions.XMLMarshalException.descriptorNotFoundInProject(XMLMarshalException.java:140)
at org.eclipse.persistence.internal.oxm.Context$ContextState.getSession(Context.java:145)
at org.eclipse.persistence.oxm.XMLContext$XMLContextState.getSession(XMLContext.java:795)
at org.eclipse.persistence.oxm.XMLContext$XMLContextState.getSession(XMLContext.java:1)
at org.eclipse.persistence.internal.oxm.Context.getSession(Context.java:466)
at org.eclipse.persistence.oxm.XMLContext.getSession(XMLContext.java:364)
at org.eclipse.persistence.oxm.XMLContext.getSession(XMLContext.java:1)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:466)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:695)
at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:655)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:301)
... 26 more
We can workaround this with something like:
JAXBElement<T> elem;
if (Context.getJaxbImplementation().equals(JAXBImplementation.ECLIPSELINK_MOXy)
&& value instanceof JAXBElement<?>) {
elem = (JAXBElement<T>) value;
Class<?> valueClass = elem.getDeclaredType();
Marshaller mar = jc.createMarshaller();
ByteArrayOutputStream bout = new ByteArrayOutputStream(256);
mar.marshal(elem, bout);
Unmarshaller unmar = jc.createUnmarshaller();
elem = (JAXBElement<T>)unmar.unmarshal(new StreamSource(new ByteArrayInputStream(
bout.toByteArray())), valueClass);
}
but is there a better way?
Disclaimer: I'm the author of JAXB2-Basics that includes the Copyable PluginĀ“ which I think fits the task pretty well.
You may be interested Copyable Plugin, it generates reflection-free strategic copy methods.
Activation in Maven (see also Using JAXB2 Basics Plugins):
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<configuration>
<extension>true</extension>
<args>
<arg>-Xcopyable</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
</plugin>
</plugins>
</configuration>
</plugin>
The plugin then generates deep, reflection-free and strategy-based clone and copyTo methods (see below). This gives you very efficient copying. You can also "copy" to an existing instance or customize what and how should be copied by specifying your own strategy. For instance, you may want to avoid copying id fields or something like that. Generated code also knows how to deal with JAXBElement.
This is a kind of code generated:
public Object clone() {
return copyTo(createNewInstance());
}
public Object copyTo(Object target) {
final CopyStrategy2 strategy = JAXBCopyStrategy.INSTANCE;
return copyTo(null, target, strategy);
}
public Object copyTo(ObjectLocator locator, Object target, CopyStrategy2 strategy) {
final Object draftCopy = ((target == null)?createNewInstance():target);
if (draftCopy instanceof IssueJIIB35) {
final IssueJIIB35 copy = ((IssueJIIB35) draftCopy);
{
Boolean nameShouldBeCopiedAndSet = strategy.shouldBeCopiedAndSet(locator, this.isSetName());
if (nameShouldBeCopiedAndSet == Boolean.TRUE) {
String sourceName;
sourceName = this.getName();
String copyName = ((String) strategy.copy(LocatorUtils.property(locator, "name", sourceName), sourceName, this.isSetName()));
copy.setName(copyName);
} else {
if (nameShouldBeCopiedAndSet == Boolean.FALSE) {
copy.name = null;
}
}
}
// ...
}
return draftCopy;
}
public Object createNewInstance() {
return new IssueJIIB35();
}
Might look a bit weird/cumbersome but it takes quite a few JAXB peculiarities into account.
Turns out the docx4j code introduced in https://github.com/plutext/docx4j/pull/163 had issues copying a JAXBElement, whether using MOXy or Sun/Oracle reference implementation.
https://github.com/plutext/docx4j/commit/b5d8b4722e814945e502da9f0516d59c498b64bb fixes it

Unmarshalling the XML using JAXB

Actually I am very new at spring and currently due to some requirement, I am working with spring-integration, I have made few JAXB classes to convert the data into XML and have to send it through webservices but in response I am getting the XML back with some new element, I want to know how to unmarshall the new XML with same JAXB classes that I have made?
I use the following component to do that (java configuration):
#Bean
public Jaxb2Marshaller jaxb2Marshaller() throws Exception {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
/* Packages with root elements (#XmlRootElement). Your JAXB classes */
marshaller.setContextPaths("...");
return marshaller;
}
#Bean
#ServiceActivator(inputChannel = "toWebServiceChannel")
public MessageHandler wsGateway() throws Exception {
ConfigWebServiceURLProvider provider = new ConfigWebServiceURLProvider(isHttps, host, port, endpoint);
/* marshaller and unmarshaller could be the same */
MarshallingWebServiceOutboundGateway gw = new MarshallingWebServiceOutboundGateway(url, jaxb2Marshaller(), jaxb2Marshaller());
gw.setOutputChannelName( "fromWebServiceChannel" );
return gw;
}

Spring Integration for SimpMessagingTemplate

I have an MVC project that do the below
#Autowired
SimpMessagingTemplate messagingTemplate;
private void sendAlarmUpdate(AlarmNotify alarmNotify) {
messagingTemplate.convertAndSend("/topic/notify/alarm",alarmNotify);
}
I am trying to convert this into Spring Integration using int-stomp:outbound-channel-adapter but i am getting exception that the message payload should be array of bytes , i tried converting my object into JSON but still the same , what is the correct way to send a STOMP JSON message from spring-integration
#Bean
public Reactor2TcpStompClient stompClient() {
Reactor2TcpStompClient stompClient = new Reactor2TcpStompClient("192.168.70.XXX", 61613);
//stompClient.setMessageConverter(new PassThruMessageConverter());
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.afterPropertiesSet();
stompClient.setTaskScheduler(taskScheduler);
stompClient.setReceiptTimeLimit(5000);
return stompClient;
}
#Bean
public StompSessionManager stompSessionManager() {
Reactor2TcpStompSessionManager stompSessionManager = new Reactor2TcpStompSessionManager(stompClient());
stompSessionManager.setAutoReceipt(true);
return stompSessionManager;
}
<int:chain input-channel="stompChannel">
<!--<int:object-to-json-transformer />-->
<int-stomp:outbound-channel-adapter stomp-session-manager="stompSessionManager" destination="/topic/notify/alarm1" id="stompAdapter" />
</int:chain>
The problem with STOMP protocol on the wire that it really requires byte[] as message body.
So, you don't have choice unless convert your JSON into byte[] manually, or provide StringMessageConverter into your stompClient instead of that commented PassThruMessageConverter.

How to force a JAXBException when marshalling for a JUnit test

I haven't been able to find a way to force a JAXBException when marshalling for a JUnit test. Does anyone have any ideas?
Here is my marshalling code:
public String toXml() {
log.debug("Entered toXml method");
String result = null;
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Config.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter writer = new StringWriter();
jaxbMarshaller.marshal(this, writer);
result = writer.toString();
} catch (JAXBException e) {
log.error(e);
}
log.debug("Exiting toXml method");
return result;
}
There are different ways to create a JAXBException during a marshal operation:
1 - Marshal an Invalid Object
You can generate a JAXBException during a marshal operation by marshalling an instance of a class that the JAXBContext isn't aware of (i.e. Take your example and use it to marshal an instance of Foo). This will produce the following exception.
Exception in thread "main" javax.xml.bind.JAXBException: class forum13389277.Foo nor any of its super class is known to this context.
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:594)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:482)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:95)
at forum13272288.Demo.main(Demo.java:27)
2 - Marshal to Invalid Output
If you try to marshal to an invalid output such as an OutputStream that has been closed:
FileOutputStream closedStream = new FileOutputStream("src/foo.xml");
closedStream.close();
jaxbMarshaller.marshal(this, closedStream);
Then you will get a MarshalException which is a subclass of JAXBException.
Exception in thread "main" javax.xml.bind.MarshalException
- with linked exception:
[java.io.IOException: Stream Closed]
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:320)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:95)
at forum13272288.Demo.main(Demo.java:27)
Caused by: java.io.IOException: Stream Closed
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:318)
at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.flushBuffer(UTF8XmlOutput.java:413)
at com.sun.xml.bind.v2.runtime.output.UTF8XmlOutput.endDocument(UTF8XmlOutput.java:137)
at com.sun.xml.bind.v2.runtime.output.IndentingUTF8XmlOutput.endDocument(IndentingUTF8XmlOutput.java:165)
at com.sun.xml.bind.v2.runtime.XMLSerializer.endDocument(XMLSerializer.java:852)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.postwrite(MarshallerImpl.java:369)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:316)
... 3 more

Resources