I am working with an API which I do not have control on, which returns XMLs.
Basically I have directory object that can contain multiple directory and file objects which are not wrapped by any tag, among few other primitive fields.
file object contains few primitive fields, and 2 lists which are wrapped by tPathList and oPathList tags.
Below is an example of such XML:
<hwreply>
<result>1</result>
<directory>
<file>
<created>DATE</created>
<modified>DATE</modified>
<name>STRING</name>
<size>INT</size>
<tPath>STRING</tPath>
<oPath>STRING</oPath>
<aPath>STRING</aPath>
<tPathList>
<tPath>STRING</tPath>
...
</tPathList>
<oPathList>
<oPath>STRING</oPath>
...
</oPathList>
</file>
<file>...</file>
...
<directory>...</directory>
<directory>...</directory>
...
<nEntries>5</nEntries>
<created>DATE</created>
<modified>DATE</modified>
</directory>
</hwreply>
I have created Directory and File objects, and OpenDirectory which is the root. When I call
OpenDirectory od = response.getEntity(OpenDirectory.class);
I get the following exception:
Exception in thread "main" java.lang.NullPointerException
at com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:290)
at com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:254)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Scope.add(Scope.java:106)
at com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty$ReceiverImpl.receive(ArrayERProperty.java:195)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.endElement(UnmarshallingContext.java:507)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.endElement(SAXConnector.java:145)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1782)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2938)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:200)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:120)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:103)
at com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider.readFrom(XMLRootElementProvider.java:115)
at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:111)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:553)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:506)
at liveperson.lphosting.plugins.cdn.proxy.highwinds.HighwindsProxy.getDirectory(HighwindsProxy.java:49)
at liveperson.lphosting.plugins.cdn.proxy.highwinds.HighwindsProxy.main(HighwindsProxy.java:59)
I figured that it relates to one of the lists that I have, but I couldn't figure where did I go wrong. Any help would be appreciated.
Thanks in advance.
Below are the classes (minus few fields/methods):
#XmlRootElement(name = "hwreply")
public class OpenDirectory extends ResponseBase {
#XmlElement(name="session")
public Session getSession() {...}
public void setSession(Session session) {...}
#XmlElement(name="directory")
public Directory getDirectory() {...}
public void setDirectory(Directory directory) {...}
}
public class Directory {
...
private List<Directory> directories;
private List<File> files;
#XmlElement(name="nEntries")
public int getnEntries() {...}
public void setnEntries(int nEntries) {...}
#XmlElement(name="name")
public String getName() {... }
public void setName(String name) {... }
#XmlElement(name="readonly")
public boolean isReadonly() {... }
public void setReadonly(boolean readonly) { ... }
#XmlElement (name="created")
public String getCreated() { ... }
public void setCreated(String created) { ... }
#XmlElement(name="modified")
public String getModified() {... }
public void setModified(String modified) {... }
#XmlElements(
#XmlElement(name="directory", type=Directory.class)
)
public List<Directory> getDirectories() {
return directories;
}
public void setDirectories(List directories) {
this.directories = directories;
}
#XmlElements(
#XmlElement(name="file", type=File.class)
)
public List<File> getFiles() {
return files;
}
public void setFiles(List files) {
this.files = files;
}
}
public class File {
private List<String> tPathList;
private List<String> oPathList;
#XmlElement(name="xferStatus")
public int getXferStatus() {...}
public void setXferStatus(int xferStatus) {...}
#XmlElement(name="size")
public int getSize() {...}
public void setSize(int size) {...}
#XmlElement(name="tPath")
public String gettPath() {...}
public void settPath(String tPath) {...}
#XmlElement(name="oPath")
public String getoPath() {...}
public void setoPath(String oPath) {...}
#XmlElementWrapper(name="tPathList")
#XmlElements(
#XmlElement(name="tPath", type=String.class)
)
public List gettPathList() {
return tPathList;
}
public void settPathList(List tPathList) {...}
#XmlElementWrapper(name="oPathList")
#XmlElements(
#XmlElement(name="oPath", type=String.class)
)
public List getoPathList() {
return oPathList;
}
public void setoPathList(List oPathList) {
this.oPathList = oPathList;
}
}
Problem is solved by OP himself, adding it as an answer.
Found the problem. If it helps anyone:
setFiles(List files) in File class, should be setFiles(List<File> files).
I also had the same exception. but the solution was different. I share it here, for future problem solvers. When you invoke JAXBContext.newInstance(), have a look at the returned object.
Usually it should be of type com.sun.xml.bind.v2.runtime.JAXBContextImpl. However if it comes from some glassfish3 library like:
jar:file.../glassfish3/glassfish/modules/jaxb-osgi.jar
that threw me the same exception. A changed the order of classpath, and finally the unmarshalling worked fine, if the JAXBContext.newInstance() finds the first implementing JAXBContext class from this jar:
jar:file:.../.m2/repository/com/sun/xml/bind/jaxb-impl/2.x.x/jaxb-impl-2.x.x.jar
Related
There is a final static member in class ToBeTestClass:
protected final static LMSServiceHelper externalService;
I mock it with
#Mock
protected LMSServiceHelper externalService;
Then I want to get different values in different test methods:
public void testMethod1() {
PowerMockito.when(externalService.getSomething).thenReturn("aaa");
}
public void testMethod2() {
PowerMockito.when(externalService.getSomething).thenReturn("bbb");
}
public void testMethod3() {
PowerMockito.when(externalService.getSomething).thenReturn("ccc");
}
However, I can't get "bbb" or "ccc" whereas always get "aaa". It seems when I set the return value first time, and it will never changes.
Anyone has met this?
#Before
public void setUp() {
Mockito.when(externalService.getSomething)
.thenReturn("aaa")
.thenReturn("ccc")
.thenReturn("ccc"); //any subsequent call will return "ccc"
}
How to tell a Mockito mock object to return something different the next time it is called?
Reset your mocked object as shown below then you will see different values
public void testMethod1() {
PowerMockito.when(externalService.getSomething).thenReturn("aaa");
Mockito.reset(externalService);
}
public void testMethod2() {
PowerMockito.when(externalService.getSomething).thenReturn("bbb");
Mockito.reset(externalService);
}
public void testMethod3() {
PowerMockito.when(externalService.getSomething).thenReturn("ccc");
Mockito.reset(externalService);
}
I want to define a java class and then use JAXB to marshalling its instances to a xml file.
The output I want looks like:
<paths>
<path action="R" kind="file" copyfrom-path="file1" copyto-path="file2">file2</path>
<path action="M" kind="file">file3</path>
</paths>
I defined a java class as follows:
#XmlRootElement(name = "paths")
#XmlAccessorType(FIELD)
public class changed_paths
{
private List<String> path;
public changed_paths()
{
path = new ArrayList<String>();
}
public List<String> getPath()
{
return path;
}
public void setPath(List<String> path)
{
this.path = path;
}
public void addPath(String p)
{
path.add(p);
}
}
Using the above java class, I can generate output xml file without the attributes of <path></path> elements. Like below:
<paths>
<path>file2</path>
<path>file3</path>
</paths>
I tried to define the attributes in changed_paths class like below :
#XmlAttribute
private String kind;
public void setKind(String kind){
this.kind = kind;
}
public String getKind(){
return this.kind;
}
But this will output a xml file with attributes "kind" in tag <paths></paths> but not in its nested <path></path> tags.
The other problem is that when the attribute name contains "-" (e.g. copyfrom-path), java won't allow me to define such variables with "-" in its name.
Can someone please tell me how to define:
1. attributes in <path></path>?
2. attributes with "-" in their names?
Can someone please give me some help?
Thank you very much!
I find the answers. To create attributes for <path></path>, I defined class path for this tag. And defined another class paths for <paths></paths> .
To create attributes with "-" in their names, I use annotation #XmlAttribute(name = "copyfrom-path")
#XmlAccessorType(FIELD)
public class path
{
#XmlAttribute
private String kind;
#XmlAttribute
private String action;
#XmlAttribute(name = "copyfrom-path")
private String copyfrom;
#XmlAttribute(name = "copyfrom-rev")
private String copyto;
#XmlValue
private String value;
public void setKind(String kind)
{
this.kind = kind;
}
public String getKind()
{
return this.kind;
}
public void setAction(String action)
{
this.action = action;
}
public String getAction()
{
return this.action;
}
public void setValue(String value)
{
this.value = value;
}
public String getValue()
{
return this.value;
}
public void setCopyfrom(String p)
{
this.copyfrom = p;
}
public String getCopyfrom()
{
return this.copyfrom;
}
public void setCopyto(String p)
{
this.copyto = p;
}
public String getCopyto()
{
return this.copyto;
}
}
#XmlRootElement(name = "paths")
#XmlAccessorType(FIELD)
public class paths
{
private List<path> paths;
public paths()
{
paths = new ArrayList<path>();
}
public List<path> getPaths()
{
return paths;
}
public void setPaths(List<path> paths)
{
this.paths = paths;
}
public void addPath(path p)
{
paths.add(p);
}
}
I have a GWT2.6.1 application. I uses a RPC call. I defined service, serviceAsync, serviceImpl. But I consistently got following errors:
INFO: javax.servlet.ServletContext log: logLevelServlet: ERROR: The serialization policy file '/analytics/E4322B1E292CEFFC5E147EAE677D2BFF.gwt.rpc' was not found; did you forget to include it in this deployment?
com.google.appengine.tools.development.ApiProxyLocalImpl log
INFO: javax.servlet.ServletContext log: logLevelServlet: ERROR: The serialization policy file '/analytics/E4322B1E292CEFFC5E147EAE677D2BFF.gwt.rpc' was not found; did you forget to include it in this deployment?
com.google.appengine.tools.development.ApiProxyLocalImpl log
INFO: javax.servlet.ServletContext log: logLevelServlet: Downloaded serialization policy from http://localhost:9876/policies/E4322B1E292CEFFC5E147EAE677D2BFF.gwt.rpc
EPARecord.java
public class EPARecord implements Serializable {
private static final long serialVersionUID = -6723643433565890894L;
private String timeStamp;
private String logLevel;
private String event;
private String comment;
public EPARecord(){}
public String getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(String timeStamp) {
this.timeStamp = timeStamp;
}
public String getLogLevel() {
return logLevel;
}
public void setLogLevel(String logLevel) {
this.logLevel = logLevel;
}
public String getEvent() {
return event;
}
public void setEvent(String event) {
this.event = event;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
LogLevelService.java
#RemoteServiceRelativePath("loglevel")
public interface LogLevelService extends RemoteService {
EPARecord[] getEAPRecords(String level) throws IllegalArgumentException;
}
LogLevelServiceAysnc.java
public interface LogLevelServiceAsync {
void getEAPRecords(String level, AsyncCallback<EPARecord[]> callback) throws IllegalArgumentException;
}
I cleard browser cache, and I clear the project and rebuild it. It always give the same erorr. I suppose EPARecord file has all String attributes and it is serializable. And in remote interface, it transfer array of EPARecord, it shall be ok without customerized implementation of serializable.
i take some problem.you can remove it and run again your app,if you have "inherits name='com.google.gwt.user.theme.clean.Clean'" code line into your *.gwt.xml file.
I had this problem when I wanted to connect to the local database with the GAE application. When I recreated my applications without GAE the problem disappeared.
I'm starting with some Java classes that I would like to be able to unmarshall from XML--I'm determining the schema as I go. I would like to use XML similar to the following:
<Person fname="John" lname="Doe">
<bio><foo xmlns="http://proprietary.foo">Blah <bar>blah</bar> blah</foo></bio>
</Person>
I'm hoping to annontate my Java classes similar to the following:
public class Person {
#XmlAttribute
public String fname;
#XmlAttribute
public String lname;
#XmlElement
public ProprietaryFoo bio;
}
I'd like to pass the <foo xmlns="http://proprietary.foo"> element and it's descendants to a compiled factory class which works like this:
FooFactory.getFooFromDomNode(myFooElement) // Returns a private ProprietaryFooImpl as an instance of the public ProprietaryFoo Interface
It seems like I need to create a DomHandler for ProprietaryFoo but I'm not quite able to figure it out (I was getting “com.xyz.ProprietaryFooImpl nor any of its super class is known to this context.") I'm also interested in XmlJavaTypeAdapter I can't figure out how to receive the ValueType as an Element.
Ended up using both an XmlAdapter and a DomHandler along with a simple Wrapper class.
public class FooWrapper {
#XmlAnyElement(FooDomHandler.class)
public ProprietaryFoo foo;
}
public class FooXmlAdapter extends XmlAdapter<FooWrapper, ProprietaryFoo> {
#Override
public ProprietaryFoo unmarshal(FooWrapper w) throws Exception {
return w.foo;
}
#Override
public FooWrapper marshal(ProprietaryFoo f) throws Exception {
FooWrapper fooWrapper = new FooWrapper();
fooWrapper.foo = f;
return fooWrapper;
}
}
/* The vendor also provides a ProprietaryFooResult class that extends SAXResult */
public class FooDomHandler implements DomHandler<ProprietaryFoo, ProprietaryFooResult> {
#Override
public ProprietaryFooResult createUnmarshaller(ValidationEventHandler validationEventHandler) {
return new ProprietaryFooResult();
}
#Override
public ProprietaryFoo getElement(ProprietaryFooResult r) {
return r.getProprietaryFoo();
}
#Override
public Source marshal(ProprietaryFoo f, ValidationEventHandler validationEventHandler) {
return f.asSaxSource();
}
}
For whatever reason, this didn't work with the standard classes from the com.sun namespace but MOXy handles it well.
I have two classes as below.
public class Destination
{
public Destination()
{
_StringCollection = new List<String>();
}
private ICollection<String> _StringCollection;
public IEnumerable<String> StringCollection
{
get
{
return _StringCollection.AsEnumerable<String>();
}
}
public void AddString(string str)
{
_StringCollection.Add(str);
}
}
public class Source
{
public List<String> StringCollection { get; set; }
}
I would like to map that for each member of source call AddString(member) on Destination.
I thought that maybe I could do something with a custom resolver but can't seem to figure out how.
No, you can't redirect to a specific method. You can expose as an ICollection, but that's it.