I am doing a unit testing which includes parsing of data with XStream parser.I used Mockito for mocking context.But the test case fails with an error log:
java.lang.RuntimeException: Method newInstance in org.xmlpull.v1.XmlPullParserFactory not mocked. See http://g.co/androidstudio/not-mocked for details.
at org.xmlpull.v1.XmlPullParserFactory.newInstance(XmlPullParserFactory.java)
at com.thoughtworks.xstream.io.xml.XppDriver.createParser(XppDriver.java:57)
at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:54)
at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:65)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1049)
at com.att.apis.metadata.MetadataHandler.execute(MetadataHandler.java:38)
at com.att.apis.services.ServerOperations.executePostOperation(ServerOperations.java:20)
at com.att.framework.helper.request.MetadataAPIHandler.executeAPIRequest(MetadataAPIHandler.java:58)
at com.att.framework.helper.request.MetadataAPIHandlerMokitoTest.executeAPIRequest(MetadataAPIHandlerMokitoTest.java:57)
The error is happening at the line " response = (MetadataResponse)xs.fromXML(iStream); " in the below code block
InputStream iStream = responseData.getInputStream();
XStream xs = new XStream();
xs.autodetectAnnotations(true);
xs.alias("helloa", A.class);
xs.alias("hellob", B.class);
xs.alias("helloc",C.class);
response = (MetadataResponse)xs.fromXML(iStream);
As per the answer from Android: XmlPullParserFactory.newInstance() creating a null factory, I added
testOptions {
unitTests.returnDefaultValues = true
}
in build.gradle.
After the update when NullPointer Exception with below log occurred.
java.lang.NullPointerException
at com.thoughtworks.xstream.io.xml.XppDriver.createParser(XppDriver.java:59)
at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:54)
at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:65)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1049)
at com.att.apis.metadata.MetadataHandler.execute(MetadataHandler.java:38)
at com.att.apis.services.ServerOperations.executePostOperation(ServerOperations.java:20)
at com.att.framework.helper.request.MetadataAPIHandler.executeAPIRequest(MetadataAPIHandler.java:58)
at com.att.framework.helper.request.MetadataAPIHandlerMokitoTest.executeAPIRequest(MetadataAPIHandlerMokitoTest.java:57)
Can anyone help me to sort out the issue
If you think that mocking XmlPullParser is not a good idea and you would rather write tests against the real parser, so you can check whether real XML documents are actually parsed correctly by your code, this is how you can solve it:
Simply add this xmlpull dependency to your app's gradle file:
testImplementation group: 'xmlpull', name: 'xmlpull', version: '1.1.3.1'
It will be used only for running the unit tests and will not be packaged in your APK
XmlPullParserFactory comes from the Android platform and therefore can not be mocked in the unit tests as they are executed with the Java VM you have installed on your computer.
You may want to use the Robolectric framework, it allows for the unit tests to make calls to the Android platform (it mocks almost everything in the whole platform)
You should refactor your code a bit and mock Xstream and all it's dependencies. For example you can externalize creation of Xstream and pass it to your method under test.
Xstream mockXstream = Mockito.mock(Xstream.class);
//mock all xstream method calls
void myMethodUnderTest(Xstream xs){
InputStream iStream = responseData.getInputStream();
xs.autodetectAnnotations(true);
xs.alias("helloa", A.class);
xs.alias("hellob", B.class);
xs.alias("helloc",C.class);
response = (MetadataResponse)xs.fromXML(iStream);
}
Related
Example feature scenario is
#JIRA_BOND_007
#manual
#manual-result:passed
#manual-last-tested:sprint-1
#manual-test-evidence:https://some.external/link.png
Scenario: Dont want Manual steps to cause step definition failure
Given John Ferguson Smart releases a new version of serenity bdd
When tester marks a test as manual
Then runner should not fail because of error "io.cucumber.junit.UndefinedStepException:"
error example:
#When("tester marks a test as manual")
public tester_marks_a_test_as_manual(){
// Write code here that turns the phrase above into concrete actions
throw new io.cucumber.java.PendingException();
**io.cucumber.junit.UndefinedStepException:**
I want these scenarios tagged #manual to show in serenity report but not cause the runner to throw error because its looking for step definitions that dont exist.
it seems that we have now way around this as per comments from John Ferguson Smart:
"However, Cucumber does not allow steps to not have a step definition (they will result in a build failure). There isn't an easy work-around to this: "
I'm using jackson-dataformat-csv to read a csv file in, and I'm getting a NoSuchMethodError when trying to parse the mappingIterator with the line
MyRecord record = (MyRecord) it.nextValue();
of this snipped (slightly modified, ex handling removed)
CsvMapper csvMapper = new CsvMapper();
CsvSchema schema = csvMapper.schemaFor(MyRecord.class);
#SuppressWarnings("rawtypes")
MappingIterator<Entry> it = csvMapper.reader(MyRecord.class)
.with(schema).readValues(filename);
List<MyRecord> records = new ArrayList<>();
while (it.hasNextValue()) {
MyRecord record = (MyRecord) it.nextValue();
records.add(record);
}
https://github.com/FasterXML/jackson-dataformat-csv/issues/49
My issue is very close to this one, except I've already tried the solution of making sure jackson-core, jackson-databind, jackson-dataformat-csv, and jackson-annotations are all the same version (2.8). It looks like there is a 2.9 that changes things now, but at my company I don't have access to 2.9. Is there some other package I could have a conflict in?
error:
Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.core.util.BufferRecycler.allocCharBuffer(II)[C
at com.fasterxml.jackson.dataformat.csv.impl.TextBuffer.findBuffer(TextBuffer.java:160)
at com.fasterxml.jackson.dataformat.csv.impl.TextBuffer.emptyAndGetCurrentSegment(TextBuffer.java:404)
at com.fasterxml.jackson.dataformat.csv.impl.CsvDecoder.nextString(CsvDecoder.java:607)
at com.fasterxml.jackson.dataformat.csv.CsvParser._handleNextEntry(CsvParser.java:678)
at com.fasterxml.jackson.dataformat.csv.CsvParser.nextToken(CsvParser.java:523)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:118)
at com.fasterxml.jackson.databind.MappingIterator.nextValue(MappingIterator.java:189)
This has been solved, although I'm still not sure about the root cause. I believe the root cause may be specific to my own use case (my company uses it's own in-house systems for local development workspaces as well as dependency management. I ended up creating a new local (and eclipse) workspace and this same code seems to be working fine now.
Background
I'm using wsimport to create what is essentially a Java webservice client, connecting to a .Net webservice that is returning datasets (unfortunately). To be more specific I'm working on a project (inbound transport) for the GeoEvent Processor suite of ESRI ArcGIS Server 10.2, but I think this might be answered on more general terms in relation to JAXB and WSDL bindings. Bear with me as I haven't touched Java since college (10+ years).
For purposes of the WSDL, the .Net DataSet is a polymorphic type whose actual layout isn't determined until run time, after the DataSet has been filled with data. This causes problems when you want to use that webservice with anything but .Net.
After some research I've managed to use wsimport to generate from the webservice wsdl. I was then able to put together a basic proof of concept program that gets results from the webservice as a DOM, then walks that DOM as a nodelist.
Reference:
JAX-WS error on WSDL file: "Error resolving component 's:schema'"
https://weblogs.java.net/blog/vivekp/archive/2007/05/how_to_deal_wit_1.html
The section on Toolkit Bindings and figure 6 in http://msdn.microsoft.com/en-us/magazine/cc188755.aspx
My wsimport looks like this (domain names have been changed to protect the innocent):
C:\Development\ArcGIS\WSDL>wsimport -b http://www.w3.org/2001/XMLSchema.xsd -b xsd.xjb -keep -p com.somecompany.services -XadditionalHeaders http://services.somecompany.com/DataRetrieval.asmx?wsdl
The Problem
Unfortunately, the same codebase that worked in my proof of concept, getting results from the webservice, fails once I implement in the ArcGIS GeoEvent Processor. My project is part of an OSGI bundle that the ArcGIS GeoEvent Processor will control. The error below is as shown in the Apache Karaf log for the GeoEvent Processor.
Based on the error, my understanding is there is a problem with how I did the binding in wsimport, referencing the generic schema per those links I have listed above. Looks like the generic schema lacks definitions for some of the elements that exist as classes generated by wsimport. Those classes appear to be properly generated when I check the output from wsimport.
I've not included the WSDL due to posting limitations, but will include in later responses if needed.
What I'm trying to figure out
How should this error be interpreted?
Why does the same wsimport generated code used to access the webservice in my basic proof of concept fail when run in the ArcGIS GeoEvent Processor?
The error mentions JAXB and SAX, I'm not consciously referencing either of those libraries in the proof of concept or the project for the ArcGIS GeoEvent Processor. Could it be that the binding/unmarshalling of the webservice is handled differently, with ArcGIS GeoEvent Processor wrapping in JAXB/SAX and the proof of concept not?
What can I do to resolve this?
Use a different, custom, xsd and xjb that spells out the expected schema for the webservice? I'm not sure exactly how that would be done.
Use something other than wsimport to generate the webservice reference classes?
Tweak something in the java environment for the ArcGIS GeoEvent Processor?
Other options?
Commit seppuku, then it's not my problem?
The Error
2014-09-23 16:10:14,365 | ERROR | ansport Listener | SomeInboundTransport | 367 - com.somecompany.arcgis.geoevent.transport.inbound.somecompanyInboundTransport - 1.0.0 | Unable to call Webservice
javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"element"). Expected elements are <{http://services.somecompany.com/}complexType>,<{http://services.somecompany.com/}annotation>,<{http://services.somecompany.com/}redefine>,<{http://services.somecompany.com/}element>,<{http://services.somecompany.com/}include>,<{http://services.somecompany.com/}attributeGroup>,<{http://services.somecompany.com/}group>,<{http://services.somecompany.com/}notation>,<{http://services.somecompany.com/}import>,<{http://services.somecompany.com/}simpleType>,<{http://services.somecompany.com/}attribute>
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)[120:org.apache.cxf.cxf-rt-frontend-jaxws:2.6.1]
at com.sun.proxy.$Proxy198.getCompanyArcgisData(Unknown Source)[367:com.somecompany.arcgis.geoevent.transport.inbound.somecompanyInboundTransport:1.0.0]
at com.somecompany.arcgis.geoevent.transport.inbound.SomeInboundTransport.callWebService(SomeInboundTransport.java:184)[367:com.somecompany.arcgis.geoevent.transport.inbound.somecompanyInboundTransport:1.0.0]
at com.somecompany.arcgis.geoevent.transport.inbound.SomeInboundTransport.run(SomeInboundTransport.java:257)[367:com.somecompany.arcgis.geoevent.transport.inbound.somecompanyInboundTransport:1.0.0]
at java.lang.Thread.run(Thread.java:722)[:1.7.0_17]
Caused by: javax.xml.bind.UnmarshalException
- with linked exception:
[com.sun.istack.SAXParseException2; lineNumber: 1; columnNumber: 651; unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"element"). Expected elements are <{http://services.somecompany.com/}complexType>,<{http://services.somecompany.com/}annotation>,<{http://services.somecompany.com/}redefine>,<{http://services.somecompany.com/}element>,<{http://services.somecompany.com/}include>,<{http://services.somecompany.com/}attributeGroup>,<{http://services.somecompany.com/}group>,<{http://services.somecompany.com/}notation>,<{http://services.somecompany.com/}import>,<{http://services.somecompany.com/}simpleType>,<{http://services.somecompany.com/}attribute>]
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:425)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:362)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:339)
at org.apache.cxf.jaxb.JAXBEncoderDecoder.doUnmarshal(JAXBEncoderDecoder.java:784)[91:org.apache.cxf.cxf-rt-databinding-jaxb:2.6.1]
at org.apache.cxf.jaxb.JAXBEncoderDecoder.access$100(JAXBEncoderDecoder.java:97)[91:org.apache.cxf.cxf-rt-databinding-jaxb:2.6.1]
at org.apache.cxf.jaxb.JAXBEncoderDecoder$1.run(JAXBEncoderDecoder.java:812)
at java.security.AccessController.doPrivileged(Native Method)[:1.7.0_17]
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:810)[91:org.apache.cxf.cxf-rt-databinding-jaxb:2.6.1]
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:644)[91:org.apache.cxf.cxf-rt-databinding-jaxb:2.6.1]
at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:157)[91:org.apache.cxf.cxf-rt-databinding-jaxb:2.6.1]
at org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:108)[87:org.apache.cxf.cxf-api:2.6.1]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)[87:org.apache.cxf.cxf-api:2.6.1]
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:798)[87:org.apache.cxf.cxf-api:2.6.1]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1667)[118:org.apache.cxf.cxf-rt-transports-http:2.6.1]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1520)[118:org.apache.cxf.cxf-rt-transports-http:2.6.1]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1428)[118:org.apache.cxf.cxf-rt-transports-http:2.6.1]
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)[87:org.apache.cxf.cxf-api:2.6.1]
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:658)[118:org.apache.cxf.cxf-rt-transports-http:2.6.1]
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)[87:org.apache.cxf.cxf-api:2.6.1]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)[87:org.apache.cxf.cxf-api:2.6.1]
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532)[87:org.apache.cxf.cxf-api:2.6.1]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)[87:org.apache.cxf.cxf-api:2.6.1]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)[87:org.apache.cxf.cxf-api:2.6.1]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)[87:org.apache.cxf.cxf-api:2.6.1]
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)[119:org.apache.cxf.cxf-rt-frontend-simple:2.6.1]
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)[120:org.apache.cxf.cxf-rt-frontend-jaxws:2.6.1]
... 4 more
Caused by: com.sun.istack.SAXParseException2; lineNumber: 1; columnNumber: 651; unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"element"). Expected elements are <{http://services.somecompany.com/}complexType>,<{http://services.somecompany.com/}annotation>,<{http://services.somecompany.com/}redefine>,<{http://services.somecompany.com/}element>,<{http://services.somecompany.com/}include>,<{http://services.somecompany.com/}attributeGroup>,<{http://services.somecompany.com/}group>,<{http://services.somecompany.com/}notation>,<{http://services.somecompany.com/}import>,<{http://services.somecompany.com/}simpleType>,<{http://services.somecompany.com/}attribute>
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:642)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:254)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:249)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:116)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.childElement(Loader.java:101)
at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.childElement(StructureLoader.java:243)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:478)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:459)
at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:242)
at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:176)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:360)
... 28 more
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"element"). Expected elements are <{http://services.somecompany.com/}complexType>,<{http://services.somecompany.com/}annotation>,<{http://services.somecompany.com/}redefine>,<{http://services.somecompany.com/}element>,<{http://services.somecompany.com/}include>,<{http://services.somecompany.com/}attributeGroup>,<{http://services.somecompany.com/}group>,<{http://services.somecompany.com/}notation>,<{http://services.somecompany.com/}import>,<{http://services.somecompany.com/}simpleType>,<{http://services.somecompany.com/}attribute>
... 39 more
The Code (snippet)
import com.somecompany.services.*; //generated by wsimport
import javax.xml.ws.*;
//...
private com.somecompany.services.DataRetrieval myWS;
private com.somecompany.services.DataRetrievalSoap port;
private byte[] callWebService(String userName, String pwd, long dataTimeFrame)
{
try
{
myWS = new com.somecompany.services.DataRetrieval();
port = myWS.getDataRetrievalSoap();
com.somecompany.services.AuthSoapHeader mySoapHeader = new com.somecompany.services.AuthSoapHeader();
mySoapHeader.setUserName(userName);
//Hash the password then set it for the SOAP header
String pwdHash = hashMD5(pwd);
mySoapHeader.setPassword(pwdHash);
Holder holder = new Holder<AuthSoapHeader>(mySoapHeader);
Date endTime = new Date();
Date startTime = new Date(endTime.getTime() - dataTimeFrame);
XMLGregorianCalendar gcEndTime = dateToGregorianTime(endTime);
XMLGregorianCalendar gcStartTime = dateToGregorianTime(startTime);
GetCompanyArcgisDataResponse.GetCompanyArcgisDataResult companyData = port.getCompanyArcgisData(gcStartTime, gcEndTime, holder);
if( ((AuthSoapHeader)holder.value).getError() != null)
{
log.error("Authentication to web services failed!");
//OSGI stop service
this.stop();
return null;
}else
log.info("Authentication to web services successful.");
//Convert the results to a java object and then to a byte array to send to the adapter
Object companyDataAny = companyData.getAny();
byte[] companyDataBytes = objectToBytes(companyDataAny);
return companyDataBytes;
}
catch(Exception ex)
{
log.error("Unable to call Webservice", ex);
//OSGI stop service
this.stop();
return null;
}
}
Environment Specifics
JDK 7u17 (1.7.0_17) 64 bit. The ArcGIS GeoEvent Processor is using this version of the JRE, so I'm locked into that version for execution. Though I've done some development in 1.7.0_51 before I realized that.
wsimport - JAX-WS RI 2.2.4-b01
ArcGIS Server 10.2
ArcGIS GeoEvent Processor Extension
Karaf (used by ArcGIS Geovent Processor to run OSGI bundles)
This is probably not the best answer on this, but it's what I came up with.
The ArcGIS GeoEvent Processor that wrapped my OSGI project appeared to be doing some additional binding/unbinding of the web service that I referenced in my application. The work-around that I employed to get that .Net (DataSet return values) web service to function in Java just wasn't acceptable to that wrapper from the GeoEvent Processor.
My Solution
Ultimately what I did was create a secondary .Net web service which took the DataSet values and converted them to JSON, and returned JSON strings. This removed the problems encountered when attempting to reference DataSet return values from the web service, now I was dealing with a simple JSON string. The wsimport of that JSON web service went smooth, no work-around required. I tucked the newly imported web service files into my java project and now have no problems.
For Reference on C# DataSet to JSON:
Using Newtonsoft.Json (http://james.newtonking.com/json). After playing with a few other libraries for JSON serialization that is what I found worked best for me.
Newtonsoft.Json is available via NuGet package
Rick Strahl's site was a big help http://weblog.west-wind.com/posts/2008/Sep/03/DataTable-JSON-Serialization-in-JSONNET-and-JavaScriptSerializer
I have a problem while transforming the xslt to pdf in java, i am following the same process posted in this link
"Java Transformation to PDF".
Error:
`
Caused by: java.lang.NoSuchMethodError: org.apache.xmlgraphics.java2d.GraphicContext.<init>(Lorg/apache/xmlgraphics/java2d/GraphicContext;)V
at org.apache.fop.render.intermediate.IFGraphicContext.<init>(IFGraphicContext.java:50)
at org.apache.fop.render.intermediate.IFGraphicContext.clone(IFGraphicContext.java:56)
at org.apache.fop.render.intermediate.IFRenderer.saveGraphicsState(IFRenderer.java:632)
at org.apache.fop.render.intermediate.IFRenderer.startViewport(IFRenderer.java:885)
at org.apache.fop.render.intermediate.IFRenderer.startVParea(IFRenderer.java:878)
at org.apache.fop.render.AbstractRenderer.renderRegionViewport(AbstractRenderer.java:289)
at org.apache.fop.render.intermediate.IFRenderer.renderRegionViewport(IFRenderer.java:731)
at org.apache.fop.render.AbstractRenderer.renderPageAreas(AbstractRenderer.java:249)
at org.apache.fop.render.AbstractRenderer.renderPage(AbstractRenderer.java:230)
at org.apache.fop.render.intermediate.IFRenderer.renderPage(IFRenderer.java:580)
at org.apache.fop.area.RenderPagesModel.addPage(RenderPagesModel.java:114)
at org.apache.fop.layoutmgr.AbstractPageSequenceLayoutManager.finishPage(AbstractPageSequenceLayoutManager.java:312)
at org.apache.fop.layoutmgr.PageSequenceLayoutManager.finishPage(PageSequenceLayoutManager.java:167)
at org.apache.fop.layoutmgr.PageSequenceLayoutManager.activateLayout(PageSequenceLayoutManager.java:109)
at org.apache.fop.area.AreaTreeHandler.endPageSequence(AreaTreeHandler.java:238)
at org.apache.fop.fo.pagination.PageSequence.endOfNode(PageSequence.java:120)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:349)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:177)
at net.sf.saxon.event.ContentHandlerProxy.endElement(ContentHandlerProxy.java:391)
at net.sf.saxon.event.ProxyReceiver.endElement(ProxyReceiver.java:174)
at net.sf.saxon.event.NamespaceReducer.endElement(NamespaceReducer.java:213)
at net.sf.saxon.event.ComplexContentOutputter.endElement(ComplexContentOutputter.java:417)
at net.sf.saxon.instruct.ElementCreator.processLeavingTail(ElementCreator.java:301)
at net.sf.saxon.instruct.Block.processLeavingTail(Block.java:409)
at net.sf.saxon.instruct.Instruction.process(Instruction.java:94)
at net.sf.saxon.instruct.ElementCreator.processLeavingTail(ElementCreator.java:298)
at net.sf.saxon.instruct.Template.applyLeavingTail(Template.java:175)
at net.sf.saxon.instruct.ApplyTemplates.applyTemplates(ApplyTemplates.java:343)
at net.sf.saxon.Controller.transformDocument(Controller.java:1736)
at net.sf.saxon.Controller.transform(Controller.java:1560)
at mypackage.v2.business.pdf.XMLtoPDF.convertXMLPDF(XMLtoPDF.java:103)
... 51 more
java.lang.ClassCastException: java.lang.NoSuchMethodError cannot be cast to java.lang.Exception
`
Please let me know what could be the problem.
As described in the documentation
Thrown if an application tries to call a specified method of a class (either static or instance), and that class no longer has a definition of that method.
Here's how this can happen. Imagine you built some code that used a library with a method called foo(). You compiled your project and then later decided to upgrade the library. You do this by overwriting the old jar file with the new one. You don't recompile your code.
But what you didn't know is the new library removed the foo() method. Now if you run your code, it will throw this exception because your compile code calls this method and it's no longer there.
In your specific case, this isn't necessarily your code with the problem. It could be that you have one library that uses another library and the problem is there (for example, Library X uses version 2 of Library Y, but you only have Library Y version 1 in your classpath). If this is happening, you need to make sure the libraries are using the version they expect.
For your specific problem, you need to find the version of the jar that has org.apache.xmlgraphics.java2d.GraphicContext in it and it needs to have a constructor that takes a... list of org/apache/xmlgraphics/java2d/GraphicContext... maybe. I forget what (L...;)V means.
I'm trying to validate an Atom feed with Java 5 (JRE 1.5.0 update 11). The code I have works without problem in Java 6, but fails when running in Java 5 with a
org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name 'xml:base' to a(n) 'attribute declaration' component.
I think I remember reading something about the version of Xerces bundled with Java 5 having some problems with some schemas, but i cant find the workaround. Is it a known problem ? Do I have some error in my code ?
public static void validate() throws SAXException, IOException {
List<Source> schemas = new ArrayList<Source>();
schemas.add(new StreamSource(AtomValidator.class.getResourceAsStream("/atom.xsd")));
schemas.add(new StreamSource(AtomValidator.class.getResourceAsStream("/dc.xsd")));
// Lookup a factory for the W3C XML Schema language
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
// Compile the schemas.
Schema schema = factory.newSchema(schemas.toArray(new Source[schemas.size()]));
Validator validator = schema.newValidator();
// load the file to validate
Source source = new StreamSource(AtomValidator.class.getResourceAsStream("/sample-feed.xml"));
// check the document
validator.validate(source);
}
Update : I tried the method below, but I still have the same problem if I use Xerces 2.9.0. I also tried adding xml.xsd to the list of schemas (as xml:base is defined in xml.xsd) but this time I have
Exception in thread "main" org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'null', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
Update 2: I tried to configure a proxy with the VM arguments -Dhttp.proxyHost=<proxy.host.com> -Dhttp.proxyPort=8080 and now it works. I'll try to post a "real answer" from home.
and sorry, I cant reply as a comment : because of security reasons XHR is disabled from work ...
Indeed, people have been mentioning the Java 5 Sun provided SchemaFactory is giving troubles.
So: did you include Xerces in your project yourself?
After including Xerces, you need to ensure it is being used. If you like to hardcode it (well, as a minimal requirement you'd probably use some application properties file to enable and populate the following code):
String schemaFactoryProperty =
"javax.xml.validation.SchemaFactory:" + XMLConstants.W3C_XML_SCHEMA_NS_URI;
System.setProperty(schemaFactoryProperty,
"org.apache.xerces.jaxp.validation.XMLSchemaFactory");
SchemaFactory factory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Or, if you don't want to hardcode, or when your troublesome code would be in some 3rd party library that you cannot change, set it on the java command line or environment options. For example (on one line of course):
set JAVA_OPTS =
"-Djavax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema
=org.apache.xerces.jaxp.validation.XMLSchemaFactory"
By the way: apart from the Sun included SchemaFactory implementation giving trouble (something like com.sun.org.apache.xerces.internal.jaxp.validation.xs.schemaFactoryImpl), it also seems that the "discovery" of non-JDK implementations fails in that version. If I understand correctly than, normally, just including Xerces would in fact make SchemaFactory#newInstance find that included library, and give it precedence over the Sun implementation. To my knowledge, that fails as well in Java 5, making the above configuration required.
I tried to configure a proxy with the VM arguments -Dhttp.proxyHost=<proxy.host.com> -Dhttp.proxyPort=8080 and now it works.
Ah, I didn't realize that xml.xsd is in fact the one referenced as http://www.w3.org/2001/xml.xsd or something like that. That should teach us to always show some XML and XSD fragments as well. ;-)
So, am I correct to assume that 1.) to fix the Java 5 issue, you still needed to include Xerces and set the system property, and that 2.) you did not have xml.xsd available locally?
Before you found your solution, did you happen to try using getResource rather than getResourceAsStream, to see if the exception would then have showed you some more details?
If you actually did have xml.xsd available (so: if getResource did in fact yield a URL) then I wonder what Xerces was trying to fetch from the internet then. Or maybe you did not add that schema to the list prior to adding your own schemas? The order is important: dependencies must be added first.
For whoever gets tot his question using the search: maybe using a custom EntityResolver could have indicated the source of the problem as well (if only writing something to the log and just returning null to tell Xerces to use the default behavior).
Hmmm, just read your "comment" -- editing does not alert people for new replies, so time to ask your boss for some iPhone or some other gadget that is connected to the net directly ;-)
Well, I assume you added:
schemas.add(
new StreamSource(AtomValidator.class.getResourceAsStream("/xml.xsd")));
If so, is xml.xsd actually to be found on the classpath then? I wonder if the getResourceAsStream did not yield null in your case, and how new StreamSource(null) would act then.
Even if getResourceAsStream did not yield null, the resulting StreamSource would still not know where it was loaded from, which may be a problem when trying to include references. So, what if you use the constructor StreamSource(String systemId) instead:
schemas.add(new StreamSource(AtomValidator.class.getResource("/atom.xsd")));
schemas.add(new StreamSource(AtomValidator.class.getResource("/dc.xsd")));
You might also use StreamSource(InputStream inputStream, String systemId), but I don't see any advantage over the above two lines. However, the documentation explains why passing the systemId in either of the 2 constructors seems good:
This constructor allows the systemID to be set in addition to the input stream, which allows relative URIs to be processed.
Likewise, setSystemId(String systemId) explains a bit:
The system identifier is optional if there is a byte stream or a character stream, but it is still useful to provide one, since the application can use it to resolve relative URIs and can include it in error messages and warnings (the parser will attempt to open a connection to the URI only if there is no byte stream or character stream specified).
If this doesn't work out, then maybe some custom error handler can give you more details:
ErrorHandlerImpl errorHandler = new ErrorHandlerImpl();
validator.setErrorHandler(errorHandler);
:
:
validator.validate(source);
if(errorHandler.hasErrors()){
LOG.error(errorHandler.getMessages());
throw new [..];
}
if(errorHandler.hasWarnings()){
LOG.warn(errorHandler.getMessages());
}
...using the following ErrorHandler to capture the validation errors and continue parsing as far as possible:
import org.xml.sax.helpers.DefaultHandler;
private class ErrorHandlerImpl extends DefaultHandler{
private String messages = "";
private boolean validationError = false;
private boolean validationWarning = false;
public void error(SAXParseException exception) throws SAXException{
messages += "Error: " + exception.getMessage() + "\n";
validationError = true;
}
public void fatalError(SAXParseException exception) throws SAXException{
messages += "Fatal: " + exception.getMessage();
validationError = true;
}
public void warning(SAXParseException exception) throws SAXException{
messages += "Warn: " + exception.getMessage();
validationWarning = true;
}
public boolean hasErrors(){
return validationError;
}
public boolean hasWarnings(){
return validationWarning;
}
public String getMessages(){
return messages;
}
}