xStream crashes when there are more fields in the XML - java

xStream
When I have the following XML code:
<xml>
<version>1.1</version>
<url>http://www.google.nl</url>
</xml>
And I read this with my Java code everything works fine, but when the XML changes, for example to:
<xml>
<test>test</test>
<version>1.1</version>
<url>http://www.google.nl</url>
</xml>
I get an error, but I want that the program doesn't stop, and don't use the field test. Is there a way to handle this exception without that the program stops?
Exception in thread "main" com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldExce ption: No such field Version.iets
---- Debugging information ----
field : iets
class : Version
required-type : Version
converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path : /Version/iets
line number : 1
version : null
-------------------------------

XStream 1.4.5 makes you simple to deal with unknown tags. Use ignoreUnknownElements for tags which are not implemented yet or has been removed and you are dealing with old xml.
http://x-stream.github.io/javadoc/com/thoughtworks/xstream/XStream.html#ignoreUnknownElements%28%29
You can also specify which particular tag you would like to ignore.

Thanks to Brian Agnew I found the answer, this is the solution:
XStream xstream = new XStream(new DomDriver()) {
protected MapperWrapper wrapMapper(MapperWrapper next) {
return new MapperWrapper(next) {
public boolean shouldSerializeMember(Class definedIn, String fieldName) {
try {
return definedIn != Object.class || realClass(fieldName) != null;
} catch(CannotResolveClassException cnrce) {
return false;
}
}
};
}
};

Related

Hazelcast - java.lang.IllegalArgumentException: key cannot be of type Data

W've just upgraded our application from Hazelcast 3.8.0 to 3.10.1.
We am getting an error message "key cannot be of type Data!" when accessing data in Hazelcast.
java.lang.IllegalArgumentException: key cannot be of type Data!
at com.hazelcast.util.Preconditions.checkNotInstanceOf(Preconditions.java:300)
at com.hazelcast.internal.nearcache.impl.DefaultNearCache.checkKeyFormat(DefaultNearCache.java:226)
at com.hazelcast.internal.nearcache.impl.DefaultNearCache.get(DefaultNearCache.java:114)
at com.hazelcast.map.impl.tx.TransactionalMapProxySupport.getCachedValue(TransactionalMapProxySupport.java:183)
at com.hazelcast.map.impl.tx.TransactionalMapProxySupport.getInternal(TransactionalMapProxySupport.java:132)
at com.hazelcast.map.impl.tx.TransactionalMapProxy.get(TransactionalMapProxy.java:110)
at com.hazelcast.client.impl.protocol.task.transactionalmap.TransactionalMapGetMessageTask.innerCall(TransactionalMapGetMessageTask.java:43)
at com.hazelcast.client.impl.protocol.task.AbstractTransactionalMessageTask.call(AbstractTransactionalMessageTask.java:34)
at com.hazelcast.client.impl.protocol.task.AbstractCallableMessageTask.processMessage(AbstractCallableMessageTask.java:35)
at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.initializeAndProcessMessage(AbstractMessageTask.java:130)
at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.run(AbstractMessageTask.java:110)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:64)
at com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:80)
at ------ submitted from ------.(Unknown Source)
I am 100% sure that the "key" We're using is a String. The code snippet looks like this:
String key = getKey(blah, blah);
TransactionContext context = client.newTransactionContext();
context.beginTransaction();
TransactionalMap<String, AppPrefs> dataMap = context.getMap(MAP_NAME);
try {
prefs = dataMap.get(key);
context.commitTransaction();
} catch (Throwable t) {
LOGGER.error("Error getting AppPrefs.", t);
context.rollbackTransaction();
}
The line of code throwing the error is:
prefs = dataMap.get(key);
There is nothing between the line of code that sets the String
String key = getKey(blah, blah);
and the line that blows :(
Following the source code through, the TransactionalMapProxySupport's method "toNearCacheKeyWithStrategy" has this logic:
final Object toNearCacheKeyWithStrategy(Object key) {
if (!nearCacheEnabled) {
return key;
}
return serializeKeys ? ss.toData(key, partitionStrategy) : key;
}
The "DefaultNearCache" object then does a
private void checkKeyFormat(K key) {
if (!serializeKeys) {
checkNotInstanceOf(Data.class, key, "key cannot be of type Data!");
}
}
So it looks like the property of "TransactionalMapProxySupport" called "serializeKeyes" must have been FALSE but the same-named property in "DefaultNearCache"must have been true :(
The history of "DefaultNearCache" in git shows that the code was changed a year ago with the message: "Changed serialize-keys default for Near Cache from true to false"
Is there some configuration I should be setting?
The config I have for the map is simply:
<near-cache name="AppPrefsCache">
<!-- Cache locally for 10 mins -->
<max-idle-seconds>600</max-idle-seconds>
</near-cache>
Ah! It appears that I can add a " serialize-keys" tag of (true|false) to this xml and set the value.
It appears that different bits of the Hazelcast codebase are assuming a different default value for "serialize-keys". Either it should be a mandatory element in the config or the default should be the same everywhere, yes?
The mentioned behavior is really a bug in Hazelcast. I've created a new GitHub issue for it, so we can handle it properly - hazelcast/hazelcast#13371.
The workaround for versions affected by the bug is to set serialize-keys to true in the near-cache configuration. The false value won't help here.
Config config = new Config();
config.getMapConfig(testName)
.setNearCacheConfig(new NearCacheConfig().setSerializeKeys(true));
Thanks for the report and great investigation, Peter.

Xpath parsing : The prefix for element is not bound

I know this question has been asked lot of times, but even after reading them i am not able to solve this issue.
Ask : I have one xml which has one node(GivenName) defined with a namespace(mpeg7) and declared at the top on the root element.
I want to parse an attribute using xpath expression(//EpisodeOf/#crid) using javax xpath. Just to clear the code works when i remove this GivenName node from the xml.
XML :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TVAMain xmlns="urn:tva:metadata:2010" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mpeg7="urn:tva:mpeg7:2008" publicationTime="2017-12-09T08:14:32Z" publisher="Gracenote, Inc." version="1"
xml:lang="EN"
xsi:schemaLocation="urn:tva:metadata:2010
http://developer.tmsapi.com/files/tva_metadata_3-1_v161.xsd
urn:tva:mpeg7:2008
http://developer.tmsapi.com/files/tva_mpeg7_2008.xsd">
<ProgramDescription>
<ProgramInformationTable>
<ProgramInformation fragmentId="416885331" programId="someid">
<BasicDescription>
<CreditsList>
<CreditsItem role="urn:mpeg:cs:RoleCS:2010:HOST" index="1">
<PersonName xml:lang="EN">
<mpeg7:GivenName xml:lang="EN">Azeb</mpeg7:GivenName>
</PersonName>
</CreditsItem>
</CreditsList>
<EpisodeOf type="Series" index="428" crid="crid://gn.tv/185326/SH007323210000"/>
</BasicDescription>
</ProgramInformation>
</ProgramInformationTable>
</ProgramDescription>
</TVAMain>
Code(In Kotlin) :
val xpath = XPathFactory.newInstance().newXPath()
xpath.namespaceContext = MyNamespaceContext()
val extractedValue = xpath.evaluate("",InputSource(StringReader(AboveXMLInStringVariable)), qName)}
class MyNamespaceContext : NamespaceContext {
override fun getNamespaceURI(prefix: String?): String {
println("checking for getnamespace")
if (prefix == null) {
throw IllegalArgumentException("No prefix provided!");
} else if (prefix.equals("mpeg7")) {
return "http://developer.tmsapi.com/files/tva_mpeg7_2008.xsd";
} else {
return XMLConstants.NULL_NS_URI;
}
}
override fun getPrefix(namespaceURI: String?): String {
return ""
}
override fun getPrefixes(namespaceURI: String?): MutableIterator<Any?>? {
return null
}
}
Getting error on xpath.evaluate function.
Caused by: org.xml.sax.SAXParseException; lineNumber: 6; columnNumber: 60; The prefix "mpeg7" for element ":GivenName" is not bound.
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:466)
... 38 more
Question :
I tried by giving NameSpaceContext to it, but it looks it is not using it. Suggestions ?
Several issues:
You do not appear to be enabling namespace awareness:
DocumentBuilderFactory.setNamespaceAware(true).
Your XML has a default namespace: urn:tva:metadata:2010.
Your getNamespaceURI() is returning the wrong value for mpeg7; it
should be returning urn:tva:mpeg7:2008.
See also:
How does XPath deal with XML namespaces?

NoraUI - "Cannot infer Type argument" error using Result.Warning<> in a custom step

I need to raise a warning during one of my scenario but i don't stop to have this error appearing : "Cannot infer type arguments for Result.Warning<>"
I actually tried to raise the Warning the same way i was raising Failure until now :
new Result.Warning<>(targetKey, Messages.format(TaroMessages.WARNING_RESOURCES_VALUE_DIFFERENCE_AFTER_REAFFECTATION, existing_value, new_value), true, oscarAccesClientPage.getCallBack());
The custom step i am using it inside is the following : I'm trying to go over a list of Element and checking that the existing value of them is the same or not as the one saved before.
protected void checkXyResourcesValue(Integer xyIterator, List<WebElement> elements, String keyParameter) throws TechnicalException, FailureException {
try {
Integer resIterator = 1;
for(WebElement element : elements) {
String targetKey = "XY" + xyIterator + "RES" + resIterator + keyParameter;
String new_value = element.getAttribute(VALUE) != null ? element.getAttribute(VALUE) : element.getText();
String existing_value = Context.getValue(targetKey) != null ? Context.getValue(targetKey) : targetKey;
if (new_value != existing_value) {
new Result.Warning<>(targetKey, Messages.format(TaroMessages.WARNING_RESOURCES_VALUE_DIFFERENCE_AFTER_REAFFECTATION, existing_value, new_value), true, oscarAccesClientPage.getCallBack());
}
resIterator++;
}
} catch (Exception e) {
new Result.Failure<>(e.getMessage(), Messages.format(TaroMessages.FAIL_MESSAGE_ACCES_CLIENT_XY_CHECK_RESOURCES_VALUE, keyParameter, xyIterator), true, oscarAccesClientPage.getCallBack());
}
}
For the method to check and saved value I actually inspired myself for the piece of code from NoraUI to save a value on Context or read it from.
I'm using Eclipse Luna 4.4.2 and i try to compile using JDK1.8.0_131.
It may be more related to me not knowing how this work in Java than a real problem so thank you in advance for your help or insights. Don't hesitate to ask if you need more information on the piece of code or the context.
new Result.Warning<>(targetKey, Messages.format(TaroMessages.WARNING_RESOURCES_VALUE_DIFFERENCE_AFTER_REAFFECTATION, existing_value, new_value), true, 0);
use 0 if you do not use any Model (data serialized) or use id of your Object in the serial.

extracting the value of a tag from xml in which xml message is coming as string

I have the below method ...
public void sendmessage( final String messageText)
{
}
and in which the parameter messageText contains a an xml message now out of this xml message i need to extract the value of an xml tag and sent it it into an integer variable
that is in the above string parameter messageText which contains an xml message there is this tag as shown below
<transferGroupId>206320940</transferGroupId>
now i want to extract the e value of this tag and strored inside a variable please advise how to achieve this
below is the complete xml message shown below..
<?l version="1.0" encoding="UTF-8"?>
<emml message="emml-transfer-lifecycle">
<messageHeader>
<businessDate>2016-01-09</businessDate>
<eventDateTime timeContextReference="London">2016-01-09T16:55:00.485
</eventDateTime>
<system id="ACSDE">
<systemId>ADS ABLO</systemId>
<systemClass>ADS</systemClass>
<systemRole>Reference</systemRole>
</system>
<timeContext id="ndon">
<location>ABLO</location>
</timeContext>
</messageHeader>
<transferEventHeader>
<transferGroupStatus>Settled</transferGroupStatus>
<transferGroupIdentifier>
<transferGroupId>206320940</transferGroupId>
<systemReference>Ghtr</systemReference>
<transferGroupClassificationScheme>Primary Identifier
</transferGroupClassificationScheme>
</transferGroupIdentifier>
</transferEventHeader>
</emml>
I have tried this approach as shown below
String tagname = "transferGroupId";
String t = getTagValue( messageText, tagname);
and then further it is calling this method ..
public static String getTagValue(String messageText, String tagname){
return messageText.split("<"+tagname+">")[1].split("</"+tagname+">")[0];
but it this does not work in the end please advise how can i overcome from this
the other thing that was advise of jsoup also i have tried as shown below but it is throwing the exception that Parser class does not have any method named xmlParser in it ..
Document doc = Jsoup.parse(messageText, "", Parser.xmlParser());
for (Element e : doc.select("transferGroupId")) {
System.out.println(e.text());
}
JSoup sounds like what you need. (It has xml parsing support)
In JSoup:
Document doc = Jsoup.parse(messageText, "", Parser.xmlParser());
for (Element e : doc.select("transferGroupId")) {
System.out.println(e.text());
}
This will print out the text of the transferGroupId, which is 206320940 in this case. You can do other things with this such as sending a message using your own methods and resources.
Hope this helps!

Retrieve namespace value of XML using digester

I am trying to extract information from a XML file and able to extract values without its properties.
Code:
public class NRusEntity {
private String code;
private String name;
private String saltForm;
getters and setters
...
Parser Class:
...
String filePath = FileUtility.getOwlFilePath();
try {
Digester digester = new Digester();
digester.setValidating(false);
//digester.setNamespaceAware(true);
digester.addObjectCreate("rdf:RDF", NRus.class);
digester.addObjectCreate("rdf:RDF/owl:Class", NRusEntity.class);
digester.addCallMethod("rdf:RDF/owl:Class/Preferred_Name", "setName", 0);
digester.addCallMethod("rdf:RDF/owl:Class/code", "setCode", 0);
/**This commented part creates exception*/
//digester.addCallMethod("rdf:RDF/owl:Class/Has_Salt_Form", "setSaltForm", 2);
//digester.addCallParam("rdf:RDF/owl:Class/Has_Salt_Form", 0);
//digester.addCallParam("rdf:RDF/owl:Class/Has_Salt_Form", 1, "rdf:resource");
digester.addSetNext("rdf:RDF/owl:Class", "addEntry");
File input = new File(filePath);
digester.parse(input);
}
...
XML Looks like this:
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#">
<owl:Class rdf:about="#z">
<Preferred_Name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">von</Preferred_Name>
<code rdf:datatype="http://www.w3.org/2001/XMLSchema#string">XY221</code>
<Has_Format rdf:resource="http://zlib.com#Ni_Hydro"/>
</owl:Class>
...
</rdf:RDF>
How can I extract the URI value
"http://zlib.com#Ni_Hydro"
from that XML line
<Has_Format rdf:resource="http://zlib.com#Ni_Hydro"/>
I can't tell exactly as your XML does not appear to quite match your code: the commented out code refers to a Has_Salt_Form element but the rdf:resource element appears on a Has_Format element. However, I can see one potential problem which may help you progress:
I'm assuming your NRusEntity class setter is something like:
public void setSaltForm(String saltForm) {
// assign saltForm, or whatever...
}
However, the digester code you have is:
digester.addCallMethod("rdf:RDF/owl:Class/Has_Salt_Form", "setSaltForm", 2);
digester.addCallParam("rdf:RDF/owl:Class/Has_Salt_Form", 0);
digester.addCallParam("rdf:RDF/owl:Class/Has_Salt_Form", 1, "rdf:resource");
This is looking for a setSaltForm method with two parameters (the first is the element body, the second the rdf:resource attribute), so will not match the simple setter, and you'll get something like "no such method" in the exception message.
So if you need the body content then try adding another set method:
public void setSaltForm(String content, String attrib) {
// content will have the element content
// attrib will have "http://zlib.com#Ni_Hydro"
}
Or if you don't need the content then drop it from the digester rules:
digester.addCallMethod("rdf:RDF/owl:Class/Has_Salt_Form", "setSaltForm", 1);
digester.addCallParam("rdf:RDF/owl:Class/Has_Salt_Form", 0, "rdf:resource");
If neither of those work can you add details of the version of digester you are using, and the exception you get.

Categories

Resources