0

I have a (maybe simple) question. In my code I want to know whether there are one or more folder in a classpath or not. First things first: my code is working when using IDE, but not when it runs in a jar file. I understood that there is the way with - especially in Spring Boot - the class PathMatchingPatternResolver to get the resources. I have done this, but I can't get my code working under *.jar. The situation is as follows: I want to look at a certain path if there are certain folder to get their names. If there are such folder, the names of them will be saved in a List. I need this List in further action. But how to get the folder from *.jar?

Here is what I have done so far:

public List<String> loadSupportedRecords(Meta metaFromTaxCase) {
  List<String> vastRecordTypes = new ArrayList<>();

  Map<String, String> values = new HashMap<>();
  values.put(TAX_TYPE, metaFromTaxCase.getTaxonomie().getKey());
  values.put(FISCAL_YEAR, metaFromTaxCase.getVeranlagungszeitraum());
  values.put(TAXONOMIE_VERSION, metaFromTaxCase.getVersionDerTaxonomie());
  var path = replaceVariablesInPathWithMapValues(vastConfigTemplatePath, values);
  var indexOfRepo = path.lastIndexOf("{record-type}/");
  var lengthOfVar = "{record-type}".length();
  var subPath = path.substring(0, indexOfRepo + lengthOfVar);

  try {
    for (Resource resource : resourcePatternResolver.getResources(subPath)) {
      vastRecordTypes.add(resource.getFilename()); // <-- This does not work
      // I know that this does not work, but this is my newest commit.
      // I tried with File Object and used the "listFiles()" method,
      // but also failed.
    }
    return vastRecordTypes;
  } catch (IOException e) {
    throw new ResourceNotFoundException(
        String.format(CLASSPATH_ERROR_MESSAGE, path, e.getMessage()));
  }
}

Is there any way to get the folder names in IDE AND in *.jar running? Thank you all for helping me as good as you can.

BenChriLev
  • 13
  • 3
  • *First things first: my code is working when using IDE, but not when it runs in a jar file.* In what way is it not working? – g00se May 25 '22 at 09:45
  • Hi. The code gives me all the folder names I want when running in the IDE, but I am not able to get any folder when running a jar. In other words: The List is always empty running in a jar. – BenChriLev May 25 '22 at 09:51
  • Resources are of course seen by a classloader as something to be read and used by an app. In a way, the vm doesn't care if they are in a jar or in the file system, but *yes* of course, those two things are distinct and you can't expect the file system to be 'detected' when running in a jar. If you're interested in seeing things in the FS then you *will* have to use `Path`/`File` and you will have to treat those as absolute, as you don't know where your jar will be run from and you'll of course have to have security permissions to read them. – g00se May 25 '22 at 09:56
  • Hi. I tried a new way to get the folder. This snippet of code works. fine in IDE, but in jar I get a FileNotFound Exception (Detailed message: "classpath resource [path/to/folder] can not be resolved to absolute file path because it does not reside in the file system: ...") `Resource resource = resourcePatternResolver.getResource(subPath); for (File filePath : Objects.requireNonNull(resource.getFile().listFiles())) { vastRecordTypes.add( filePath.getAbsolutePath().substring(filePath.getAbsolutePath().lastIndexOf("/") + 1)); } return vastRecordTypes;` – BenChriLev May 25 '22 at 10:41
  • Does this answer your question? [How can I access a folder inside of a resource folder from inside my jar File?](https://stackoverflow.com/questions/11012819/how-can-i-access-a-folder-inside-of-a-resource-folder-from-inside-my-jar-file) – pringi May 25 '22 at 10:52
  • @pringi thx for this link. Unfortunately it doesn't solve my problem. As another User mentioned: "Only works for single-jar file, doesn't work to extract resources from dependencies in another jar" – BenChriLev May 25 '22 at 11:08
  • *Hi. I tried a new way to get the folder* You seem to have misunderstood [or ignored ;)] my comment – g00se May 25 '22 at 11:15
  • @g00se thx for your answer. And, yes, I misunderstood it. But for now I have a solution that works perfectly in "both worlds" IDE and jar. I will post my code and explain what I have done. – BenChriLev May 25 '22 at 12:59

1 Answers1

0

Finally I got things work. My code runs as follows:

public Set<String> loadSupportedRecords(Meta metaFromTaxCase) {
  Set<String> vastRecordTypes = new HashSet<>();
  Map<String, String> values = new HashMap<>();
  values.put(TAX_TYPE, metaFromTaxCase.getTaxonomie().getKey());
  values.put(FISCAL_YEAR, metaFromTaxCase.getVeranlagungszeitraum());
  values.put(TAXONOMIE_VERSION,metaFromTaxCase.getVersionDerTaxonomie());
  var path = replaceVariablesInPathWithMapValues(vastConfigTemplatePath, values);

  try {
    for (Resource resource : resourcePatternResolver.getResources(path)) {
      vastRecordTypes.add(((ClassPathResource) resource).getPath().split("/")[8]);
    }
    return vastRecordTypes;
  } catch (IOException e) {
    throw new ResourceNotFoundException(
      String.format(CLASSPATH_ERROR_MESSAGE, path, e.getMessage()));
  }
}

As I learned, it is not possible to get "folder" in jar environment. It seems that all is treated as a file. So I searched the file-tree and used the above split method to get the individual folder name. In my code I can be sure, that the first 8 elements of the Array are always the same, so it can be hard coded. I also used a Set now instead of a List, to avoid double inserts (because there are a lot of files underneath the folder). Thanks to all.

BenChriLev
  • 13
  • 3