Marshalling fails with exception about MarshallerImpl not known to this context - java

I have a relatively simple package of 8 Java classes generated from an XML schema using JAXB XJC. I also have a utility class to marshal and unmarshal instances of the class.
This works
The utility class can successfully unmarshal a valid XML document into an instance of the ‘root’ class WordMergeInfo. For example this works fine:
JAXBContext jc = JAXBContext.newInstance(WordMergeInfo.class);
Unmarshaller um = jc.createUnmarshaller();
return (WordMergeInfo)um.unmarshal(inputStream);
This doesn’t work
But marshalling to a string fails. In this code:
JAXBContext jc = JAXBContext.newInstance(WordMergeInfo.class);
Marshaller m = jc.createMarshaller();
StringWriter writer = new StringWriter();
m.marshal(m, writer);
return writer.toString();
the call to Marshaller.marshal fails with the following error:
javax.xml.bind.JAXBException: class com.sun.xml.bind.v2.runtime.MarshallerImpl 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)
As I understand it, nor any of its super class is known to this context means that a JAXB class needed for marshalling cannot be found. So why can’t one of the JAXB implementation classes be found, when the same class is in the stack trace?
Context
This error showed up in a unit test of my class, run under Maven. The dependencies are:
javax.xml.bind:jaxb-api:2.1
com.sun.xml.bind:jaxb-impl:2.1.13
I got the same error with earlier versions of these (2.0 and 2.0.3, respectively).
The Maven test class path is:
C:\Users\mstra.CUSTMAN\Workspace\DARTCorrModule\xml\target\test-classes
C:\Users\mstra.CUSTMAN\Workspace\DARTCorrModule\xml\target\classes
C:\Users\mstra.CUSTMAN\.m2\repository\javax\xml\bind\jaxb-api\2.1\jaxb-api-2.1.jar
C:\Users\mstra.CUSTMAN\.m2\repository\javax\xml\stream\stax-api\1.0-2\stax-api-1.0-2.jar
C:\Users\mstra.CUSTMAN\.m2\repository\javax\activation\activation\1.1\activation-1.1.jar
C:\Users\mstra.CUSTMAN\.m2\repository\com\sun\xml\bind\jaxb-impl\2.1.13\jaxb-impl-2.1.13.jar
C:\Users\mstra.CUSTMAN\.m2\repository\junit\junit\4.8.2\junit-4.8.2.jar
C:\Users\mstra.CUSTMAN\.m2\repository\org\mockito\mockito-all\1.8.5\mockito-all-1.8.5.jar
C:\Users\mstra.CUSTMAN\.m2\repository\javax\ejb\ejb-api\3.0\ejb-api-3.0.jar
C:\Users\mstra.CUSTMAN\.m2\repository\org\slf4j\slf4j-api\1.6.4\slf4j-api-1.6.4.jar
Any insight is appreciated.

nor any of its super class is known to this context
This means that the class is not registered as a marshallable class in the JAXB context.
Your error is on this line:
m.marshal(m, writer);
You are trying to marshal the marshaller itself. You probably meant to marshal a WordMergeInfo object.

Related

How to stop JAXB from escaping certain characters when converting java class to XML String? [duplicate]

This question already has answers here:
How to generate CDATA block using JAXB?
(10 answers)
JAXB Marshalling Unmarshalling with CDATA
(7 answers)
Closed 2 years ago.
I have run into a few issues in my Java 1.8 application when trying to use JAXB to marshal my Java object into an XML string. The first issue was that by default marshalling escapes < and > so when i was trying to wrap some fields in
<![CDATA[ my-field-value ]]>
it was being turned into
<![CDATA[ my-field-value ]]>
Which breaks functionality of using CDATA in the first place. I used a custom character handler according to some comments from How to prevent JAXB escaping a string. Everything is working for me now but i have heard that im not supposed to use com.sun.xml.internal.* packages and currently I am doing so like this (notice the use of internal):
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
JAXBContext jc = JAXBContext.newInstance(MyClass.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(
"com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler",
new MyCustomCharacterHandler());
return marshaller;
Where MyCustomCharacterHandler is declared like so (note the use of internal):
import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;
public class XmlCdataCharacterHandler implements CharacterEscapeHandler {
...
}
This combination is working fine for me but when modifying my code to get rid of .internal.* like so using this dependency:
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.7</version>
</dependency>
import com.sun.xml.bind.marshaller.CharacterEscapeHandler;
public class XmlCdataCharacterHandler implements CharacterEscapeHandler {
...
}
JAXBContext jc = JAXBContext.newInstance(PrintPack.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(
"com.sun.xml.bind.marshaller.CharacterEscapeHandler",
new MyCustomCharacterHandler());
return marshaller;
My server will no longer start and is getting a JAXBException with the following message:
name: com.sun.xml.bind.marshaller.CharacterEscapeHandler value: com.fmrco.research.search.handlers.MyCustomCharacterHandler#1f3d4305
Which makes me think that my custom handler which implements the CharacterEscapeHandler is no longer being used correctly. Does anyone know how to fix this so i can keep this implementation while avoiding com.sun.xml.internal.* packages? Is there a better/newer way to turn a java class into an XML string? Seems like I should not be stuck on this for as long as I have been. Thank you!

JAXB Exception: Class not known to this context while marshalling

I am getting below error while marshalling. I generated xml's from schemas.
[javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.internal.SAXException2: class org.com.AccountsComplexType nor any of its super class is known to this context.
After a little research, some people says "Try adding #XmlSeeAlso(...class)" but the problem is AccountsComplexType class is not a XmlRootElement.
Is there any idea what am I doing wrong?
If you generated the classes form an XML schema then you should bootstrap the JAXBContext from the package name of the generated model or the ObjectFactory class.

Generate sample XML from JAXB using Eclipse

Let's say I've created JAXB class in eclipse. (Using #XmlRootElement, #XmlAttribute, etc)
Is there a plugin which generate me example XML preview from my JAXB annotated class ?
There are XML Editors, which can create Sample XMLs from the XSD, for example we use Altova XMLSpy.
There is a plugin called " org.jvnet.jaxbw.eclipse_1.0.0" which you need to keep in eclipse lib folder.
Below is the link for guide.
http://www.xyzws.com/scdjws/studyguide/jaxb_samples2.0.html
You can use JAXB marshaller for doing this. Just a 3 three lines of code.
File file = new File("D:\\generatedFile.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Myclass.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(obj, file);
generatedFile.xml will contains the XML equivalent of your annonated java bean(Myclass)

how to use jaxb to create java objects

I am trying to create java objects from xml file. I am using jaxb(unmarshalling) to create java objects.I am getting errors javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"schema"). Expected elements are
I did some google and found out that, we need xsd file to do that... so I converted it to xsd using apache inst2xsd tool. I am using following java code:
import java.io.FileNotFoundException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="report")
public class Report
{
public static void main(String [] args) throws FileNotFoundException
{
try
{
JAXBContext jc = JAXBContext.newInstance(new Class[] {com.bcbsks.testjb.Report.class});
Unmarshaller um = jc.createUnmarshaller();
Report myJAXBObject = (Report)um.unmarshal(new java.io.FileInputStream("report.xsd"));
}
catch( UnmarshalException ue )
{
ue.printStackTrace();
}
catch( JAXBException je )
{
je.printStackTrace();
}
}
}
But I am getting fol;owing error:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"schema"). Expected elements are (none)
Can you please tell me whats wrong I am doing?
Any help is greatly appreciated.
I think you are missing a few steps. You didn't post what report.xsd is, nor a sample xml, so I'm going to take a few guesses.
For starters, you are trying to unmarshal the xsd and not xml, which is itself the root of the problem. That being said, your Report.java class does not look properly generated so it is unlikely that your unmarshalling would work even if you tried against your xml file.
If you have a properly created XSD file, the first thing you should do is create the JaxB POJOs using xjc. xjc comes installed with java, and you use it to create annotated java classes from the xsd. It will also create 2 additional files - ObjectFactory.java and package-info.java which are used by JAXB. (You can specify the output path using the -d param (see --help for the full list of switches)
xjc -d c:\dev\myproject\src\main\java report.xsd
Once you have those files generated, you have to create your JAXBContext based on that package/file.
JAXBContext jc = JAXBContext.newInstance(something.generated.Report.class);
Unmarshaller um = jc.createUnmarshaller();
Report myJAXBObject = (Report)um.unmarshal(new java.io.FileInputStream("report.xsd"), Report.class).getValue();
The unmarshaller generates a JAXBElement, from which you can extract the actual report class.
Hope this helps.
There are no properties on the bean you are trying to unmarshal. But more importantly, you are trying to deserialize your object from the XSD itself. The error message is a good indicator here:
unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"schema")
JAXB is spitting out this error message because it is attempting to map the XSD's metadata to properties of your bean. Which of course, your bean doesn't actually have any. The next part of the error message indicates as much:
Expected elements are (none)
You need to define your Java Bean properly (put some properties on it!), and actually get an XML file that represents the serialized version of your bean.

Can I replace jaxb.properties with code?

I am using some non-standard extensions from EclipseLink's implementation of JAXB, and to enable that implementation, I have to configure it using jaxb.properties. Works well.
However, due to a build error, the properties file was not included in the proper place, resulting in the default JAXB being used, which without any errors just continued to parse the XML file, ignoring the non-standard extension, leaving me with a non-working bean.
To make this more robust, I'd like to get rid off the properties file and specify the context configuration in code. I already have a compile-time dependency on EclipseLink because of their annotations, and I do not need this part configurable at deploy time (in fact, seeing what can go wrong, I do not want it configurable).
You could do the following to get an EclipseLink JAXB (MOXy) JAXBContext without a jaxb.properties file:
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
public class Demo {
public static void main(String[] args) throws Exception {
//JAXBContext jc = JAXBContext.newInstance(Animals.class);
JAXBContext jc = JAXBContextFactory.createContext(new Class[] {Animals.class}, null);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum6871469/input.xml");
Animals animals = (Animals) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(animals, System.out);
}
}

Categories

Resources