How to get a File reference from within a JAR - java

First of all I would like to add that I probably have tried every proposed solution on SO about this issue but still cant get it working.
So this is my problem...
I have an application for parsing XML files. I select an xml file (source) and I validate it against an xsd (this is the file inside my JAR that I cant access). Running the code from within my IDE works fine:
xsd = new File(getClass().getResourceAsStream("xsds/2014/schema.xsd").getFile());
System.out.println(xsd.getAbsolutePath());
//returns: C:\Users\xxx\Desktop\Documents\NetBeansProjects\JavaXMLValidator\build\classes\app\xsds\2014\schema.xsd
But when I build by application to JAR file and I run it I cant get the reference to that file.
When I run the application from within my JAR i get this:
//returns: C:\Users\xxx\Desktop\Documents\NetBeansProjects\JavaXMLValidator\dist\file:C:\Users\xxx\Desktop\Documents\NetBeansProjects\JavaXMLValidator\dist\JavaXMLValidator.jar!\app\xsds\2014\schema.xsd
The path looks ok (i think) but I cant get a correct reference to my file in the code:
Source schemaFile = new StreamSource(xsd);
Schema schema = null;
try {
schema = factory.newSchema(schemaFile);
} catch (SAXException ex) {
JOptionPane.showMessageDialog(null, "Invalid XML Schema Selected!!!\n Exception: "+this.getStackTraceString(ex," "));
return;
}
I get the exception:
SAXParseException: schema_reference.4: Failed to read schema document
'C:\Users\xxx\Desktop\Documents\NetBeansProjects\JavaXMLValidator\dist\file:C:\Users\xxx\Desktop\Documents\NetBeansProjects\JavaXMLValidator\dist\JavaXMLValidator.jar!\app\xsds\2014\schema.xsd',
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>
........
Can anyone suggest a way that I could have a correct reference to the xsd file withing the JAR?
Thanks a lot for any help

As MadProgrammer says, use the URL:
URL xsd = getClass().getResource("xsds/2014/schema.xsd");
Schema schema = null;
try {
schema = factory.newSchema(xsd);
} catch (SAXException ex) {
JOptionPane.showMessageDialog(null, "Invalid XML Schema Selected!!!\n Exception: "+this.getStackTraceString(ex," "));
return;
}

For example there is a project with such structure:
testproject
xsdfolder
schema.xsd
javaclassfolder
SomeClass.java
public static class SomeClass {
public static URL getLocalXsd() throws MalformedURLException {
URL baseUrl = SomeClass.class.getResource(SomeClass.class.getSimpleName() + ".class");
return new URL(baseUrl, "../xsdfolder/schema.xsd");
}
}

Related

Premature end of file exception on XML file parsing occurs frequently but not regularly.

I am currently trying to run a thread to read files from a directory and parse it.
The thread is to continuously watch the directory and send the listened file to process to parse.
I am facing "Premature end of file - org.xml.sax.SAXParseException" on continuously placing files in the specified directory using FTP.
I have tried checking for completion of file transfer and there is no error there.
I have not used inputSource/InputStream to read the file. In addition to that, I make sure that I am not reading the empty file. I just used Dom parser parse method to parse a given file.
I will attach both XML file and the java program for further reference.
I have read many blogs and links. However, no luck. Any assistance would be really helpful.
public class DirectoryWatcher implements Runnable {
private DocumentBuilderFactory factory;
private XPath xpath;
private Document doc;
public DirectoryWatcher() {
this.factory = DocumentBuilderFactory.newInstance();
this.factory.setNamespaceAware(true); // XML contains name space pattern. Hence without configuration of name
// space, XML will not be parsed
this.xpath = XPathFactory.newInstance().newXPath();
}
#Override
public void run() {
while (!cancel) {
try {
for (String file : directory.list(filter)) {
doc = factory.newDocumentBuilder().parse(directory.getAbsolutePath() + File.separator + file);
markAsProcessed(file);
TimeUnit.MILLISECONDS.sleep(interval);
}
} catch (InterruptedException e) {
cancel = true;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Error while parsing the file xx/parked.xml Premature end of file.
[Ljava.lang.StackTraceElement;#38661fd
org.xml.sax.SAXParseException; systemId: file:///home/sample.xml ;

File not reading in selenium - maven framewaork

I tried to create a quick framework. in that I created below-mentioned classes:
Config file(All browsers path)
configDataProvider java class(reads the above file)
BrowserFactory class(has firefox browser object)
configDataProviderTest class(access data from dconfigDataProvider class)
now its not reading the paths mentioned in config.properties file.
I have provided all correct path and attached screenshots:
Looks like a problem is at your ConfigDataProvider class.
Firstly, you using Maven for building your project. Maven has defined project structure for code sources and for resources:
/src/main/java
/src/main/resorces
Thus, much better to put your .properties file there.
Second, you don't need to set the full path to your config file.
Relative path will be just enough. Something like below:
public class PropertiesFileHandler {
private static Logger log = Logger.getLogger(PropertiesFileHandler.class);
public static final String CONFIG_PROPERTIES = "src/main/resources/config.properties";
public static final String KEY = "browser.type";
public static BrowserType readBrowserType() {
BrowserType browserType = null;
Properties properties = new Properties();
try (InputStream inputStream = new BufferedInputStream(new FileInputStream(CONFIG_PROPERTIES))) {
properties.load(inputStream);
browserType = Enum.valueOf(BrowserType.class, properties.getProperty(KEY));
} catch (FileNotFoundException e) {
log.error("Properties file wasn't found - " + e);
} catch (IOException e) {
log.error("Problem with reading properties file - " + e);
}
return browserType;
}
}
Lastly, if you are building framework you don't need to put everything under src/main/test. This path specifies tests with future possibilities to be executed with maven default lifecycle - mvn test.
The core of your framework can look like:
Two things which I noticed:
Don't give path in your properties path within ""
all the path seperators should be replaced with double backward slash \\ or single forward slash /

Loading file from /src/main/resources

I have an XML schema file in /src/main/resources/vast_2.0.1.xsd.
I need to load it and use it to validate my XML file.
This is what's happening:
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
File schemaFile = new File("/src/main/resources/vast_2.0.1.xsd");
try {
Schema schema = scehmaFactory.newSchema(schemaFile);
Validator validator = schema.newValidator();
Source sourceXMLFile = new StreamSource(validationRequest.xmlInputStream);
validator.validate(sourceXMLFile);
} catch (SAXException e) {
responseEngine.addFailedCheck("NON_VAST_COMPLIANT", "Does not meet VAST 2.0 XML schema specifications");
} catch (IOException e) {
// should not reach here
}
For some reason, after the File schemaFile = new File... line, it ceases to run (using print statements). Am I loading the file incorrectly?
I assume from your directory structure that you are using maven. In maven project, src/main/resources is always in the classpath so you need to specify just the file name without the path. Try this:
File schemaFile = new File("vast_2.0.1.xsd");

How to read a file in current directory through Java Class in another directory

I am working on Linux OS.
I am facing trouble parsing & transforming the XML file though Java.
Location of Java XMLTransform.class: /home/apps/source (this path is present in CLASSPATH)
Location of XML file (working directory): /home/apps/nk/working/payload.xml
When I am inside the "Working Directory", I am invoking XMLTransform.class passing XML filename payload.xml to it but getting following error:
XML-22004: (Fatal Error) Error while parsing input XML document (Invalid InputSource.).
---------
oracle.xml.parser.v2.XMLParseException: Invalid InputSource.
at oracle.xml.parser.v2.XMLError.flushErrors1(XMLError.java:320)
at oracle.xml.parser.v2.XMLReader.pushXMLReader(XMLReader.java:248)
at oracle.xml.parser.v2.XMLParser.parse(XMLParser.java:202)
at oracle.xml.jaxp.JXTransformer.transform(JXTransformer.java:321)
at TransformationEngine.main(TransformationEngine.java:30)
It is clear that class is not able to resolve the file name.
Please give pointers as to how I can resolve this?
Note: invoice_transformer.xsl is placed in same directory as .class file and CLASS file is able to read it.
Java Code:
import javax.xml.transform.*;
import java.io.*;
public class TransformationEngine {
public static void main(String[] args){
String payloadFileName = args[0];
String xslFile = "invoice_transformer.xsl";
InputStream is = java.lang.ClassLoader.getSystemResourceAsStream(xslFile);
InputStream pfis = java.lang.ClassLoader.getSystemResourceAsStream(payloadFileName);
try{
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new javax.xml.transform.stream.StreamSource(is));
transformer.transform(new javax.xml.transform.stream.StreamSource(pfis),new javax.xml.transform.stream.StreamResult(new FileOutputStream("IDMpayload.csv")));
}
catch(Exception e){
e.printStackTrace();
}
}
}
getSystemResourceAsStream() looks for the resource in the CLASSPATH. You don't have /home/apps/nk/working/ in your CLASSPATH (do you?).
Instead use FileInputStream (as suggested by #Banthar )

Writing to a file inside of a jar

I am having a problem writing to a .xml file inside of my jar. When I use the following code inside of my Netbeans IDE, no error occurs and it writes to the file just fine.
public void saveSettings(){
Properties prop = new Properties();
FileOutputStream out;
try {
File file = new File(Duct.class.getResource("/Settings.xml").toURI());
out = new FileOutputStream(file);
prop.setProperty("LAST_FILE", getLastFile());
try {
prop.storeToXML(out,null);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
}
try {
out.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
}
}
However, when I execute the jar I get an error saying:
IllegalArguementException: uri is not hierachal
Does anyone have an idea of why it's working when i run it in Netbeans, but not working when i execute the jar. Also does anyone have a solution to the problem?
The default class loader expects the classpath to be static (so it can cache heavily), so this approach will not work.
You can put Settings.xml in the file system if you can get a suitable location to put it. This is most likely vendor and platform specific, but can be done.
Add the location of the Settings.xml to the classpath.
I was also struggling with this exception. But finally found out the solution.
When you use .toURI() it returns some thing like
D:/folderName/folderName/Settings.xml
and hence you get the exception "URI is not hierarchical"
To avoid this call the method getPath() on the URI returned, which returns something like
/D:/folderName/folderName/Settings.xml
which is now hierarchical.
In your case, the 5th line in your code should be
File file = new File(Duct.class.getResource("/Settings.xml").toURI().getPath());

Categories