1

Error :

java.io.FileNotFoundException: class path resource [xml/ruleSet.xml] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app/target/******-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/xml/ruleSet.xml

Code :

File ruleSet = new ClassPathResource("xml/ruleSet.xml").getFile();
pmdConfiguration.setReportFormat("text");
pmdConfiguration.setRuleSets(ruleSet.getAbsolutePath());

I need to insert the full file into the setRuleSets method, how will FileInputStream help me here?

FileInputStream ruleSet = new FileInputStream(ClassLoader.getSystemResource
                    ("xml/ruleSet.xml").getPath());

Should I recreate a temp file by reading the fileinput stream and pass that file path to setRuleSets method?

Juan Carlos Mendoza
  • 5,736
  • 7
  • 25
  • 50
Nagendra K S
  • 111
  • 5

2 Answers2

0

The fundamental problem is that there is no path in the file system namespace for a resource in a JAR file. That is why ClassPathResource::getFile is throwing an exception, and it is also why URL::getPath.

There is an alternative. Use an InputStream, not a FileInputStream, and use the classloader API method for opening a resource as a stream.

Change:

    FileInputStream ruleSet = new FileInputStream(ClassLoader.getSystemResource
                    ("xml/ruleSet.xml").getPath());

to

    InputStream ruleSet = ClassLoader.getSystemResourceAsStream("xml/ruleSet.xml");

In this case, this won't work because PMDConfiguration::setRuleSets doesn't take a stream argument.

However, the javadoc states:

public void setRuleSets(String ruleSets)

Set the command1 separated list of RuleSet URIs.

Since the getResource methods return a URL, you should be able to do this:

    pmdConfiguration.setRuleSets(
        ClassLoader.getSystemResource("xml/ruleSet.xml").toString();

UPDATE

If getSystemResource or getSystemResourceAsStream fails, then either the resource does not exist (in the JARs, etc on the runtime classpath), the path is incorrect, or you should be using getResource or getResourceAsStream.


1 - The word "command" is a typo. It should be "comma".

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    adding toString to "ClassLoader.getSystemResource("xml/ruleSet.xml").toString()" fails, I also tried `pmdConfiguration.setRuleSets( ClassLoader.getSystemResource("xml/ruleSet.xml").getPath());` it passes in local but fails in heroku. System.out.println(ClassLoader.getSystemResource("xml/ruleSet.xml")); System.out.println(ClassLoader.getSystemResourceAsStream("xml/ruleSet.xml")); Both returns null. – Nagendra K S Apr 01 '18 at 04:16
0

Ok So I figured out what to do here,

We already have input stream, thus I converted input stream to a temp file, and used that file.getPath.

ClassLoader classLoader = this.getClass().getClassLoader();
InputStream resourceAsStream = classLoader.getResourceAsStream("xml/ruleSet.xml");
String ruleSetFilePath = "";
if(resourceAsStream != null){
    File file = stream2file(resourceAsStream);
    ruleSetFilePath = file.getPath();

}
pmdConfiguration.setRuleSets(ruleSetFilePath);

public static File stream2file (InputStream in) throws IOException {
final File tempFile = File.createTempFile("ruleSet", ".xml");
tempFile.deleteOnExit();
try (FileOutputStream out = new FileOutputStream(tempFile)) {
    IOUtils.copy(in, out);
}
return tempFile;
}
Nagendra K S
  • 111
  • 5