1

I am trying to get .cer files packed inside a jar and install them dynamically to keystore using java .

private List<File> doSomething(Path p)  {
       
        List<java.io.File>FileList=new ArrayList<>();
        try {
            
            int level = 1;
            if (p.toString().equals("BOOT-INF/classes/certs")) {
                level = 2;

                Stream<Path> walk = Files.walk(p, level);
                for (Iterator<Path> it = walk.iterator(); it.hasNext(); ) {
                    System.out.println(it.next());//getting all .cer files in the folder
                      FileList.add(it.next().toFile());//getting an error UnsupportedOperationException Path not associated with
                }
                
                logger.info("fileList" + FileList.size());
            }
        }
        catch(Exception e)
        {
            logger.error("error-----------"+e);
        }
        return FileList;
    }

I am getting UnsupportedOperationExceptionin toFile(), believe this is because I am trying to access file inside a jar. Is there any way to conver this Path(nio.file.Path) to actual file or stream?

4
  • 1
    Did your Paths come from a zip file system? Entries in a .zip file or .jar file are not actual files, they’re parts of a single archive file. Commented Oct 11, 2020 at 20:15
  • they are coming from a jar file Commented Oct 12, 2020 at 4:26
  • I also have this issue. Commented Oct 12, 2020 at 5:45
  • 1
    If they’re inside a .jar file, they are not files and they cannot be represented with Paths. Entries in a .jar file are resources and must be read with getResource or getResourceAsStream. There is no safe way to dynamically list resources in a .jar file. You should include a text file in your .jar file which lists the resource path of each certificate. Commented Oct 12, 2020 at 11:31

1 Answer 1

1

Path#toString() won't return the path with forward slashes (/) like the string path you are comparing to. It returns it with back-slashes (\) so your comparison won't ever become true.

When reading paths from the local file System always use the path or file separator related to the System. To do this you can use the String#replaceAll() method to convert any path name slashes to what is appropriate for the file system your code is operating on, for example:

String pathToCompare = "BOOT-INF/classes/certs"
                       .replaceAll("[\\/]", "\\" + File.separator);

This should work fine:

private List<java.io.File> doSomething(java.nio.file.Path p) {
    java.util.List<java.io.File> FileList = new java.util.ArrayList<>();
    try {
        int level = 1;
        String pathToCompare = "BOOT-INF/classes/certs"
                               .replaceAll("[\\/]", "\\" + File.separator);
        if (p.toString().equals(pathToCompare)) {
            level = 2;
            java.util.stream.Stream<Path> walk = java.nio.file.Files.walk(p, level);
            for (java.util.Iterator<Path> it = walk.iterator(); it.hasNext();) {
                System.out.println(it.next());//getting all .cer files in the folder
                FileList.add(it.next().toFile());//getting an error UnsupportedOperationException Path not associated with
            }
        }
    }
    catch (Exception e) {
        System.err.println(e);
    }
    return FileList;
}

EDIT:

If you want to base your listing on specific file extensions and or the contents of a JAR file then you will need to do something a little different. The code below is very similar to the code you have been using with the exception that:

  • the method name is changed to getFilesList();
  • the listing is returned as List<String> instead of List<File>;
  • the depth level is now an argument supplied to the method (always make sure the depth Level is adequate enough to carry out the task);
  • An optional String args argument (named: onlyExtensions) has been added to the method so that one (or more) file name extensions can be applied to return a list that contains only paths where the file names contain the extension(s) applied. If an extension supplied happens to be ".jar" then the contents of that JAR file will also be applied to the returned List. If nothing is supplied then all files are returned in the list.

For JAR files a helper method is also provided:

Modify any of this code as you see fit:

public static List<String> getFilesList(String thePath, int depthLevel, String... onlyExtensions) {
    Path p = Paths.get(thePath);
    java.util.List<String> FileList = new java.util.ArrayList<>();
    try {
        java.util.stream.Stream<Path> walk = java.nio.file.Files.walk(p, depthLevel);
        for (java.util.Iterator<Path> it = walk.iterator(); it.hasNext();) {
            File theFile = it.next().toFile();
            if (onlyExtensions.length > 0) {
                for (String ext : onlyExtensions) {
                    ext = ext.trim();
                    if (!ext.startsWith(".")) {
                        ext = "." + ext;
                    }
                    if (!theFile.isDirectory() && theFile.getName().substring(theFile.getName().lastIndexOf(".")).equalsIgnoreCase(ext)) {
                        FileList.add(theFile.getName() + " --> " + theFile.getAbsolutePath());
                    }
                    else if (!theFile.isDirectory() && theFile.getName().substring(theFile.getName().lastIndexOf(".")).equalsIgnoreCase(".jar")) {
                        List<String> jarList = getFilesNamesFromJAR(theFile.getAbsolutePath());
                        for (String strg : jarList) {
                            FileList.add(theFile.getName() + " --> " + strg);
                        }
                    }
                }
            }
            else {
                FileList.add(theFile.getAbsolutePath());
            }
        }
    }
    catch (Exception e) {
        System.err.println(e);
    }
    return FileList;
}

The JAR file helper method:

public static java.util.List<String> getFilesNamesFromJAR(String jarFilePath) {
    java.util.List<String> fileNames = new java.util.ArrayList<>();
    java.util.zip.ZipInputStream zip = null;
    try {
        zip = new java.util.zip.ZipInputStream(new java.io.FileInputStream(jarFilePath));
        for (java.util.zip.ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
            fileNames.add(entry.getName());
        }
    }
    catch (java.io.FileNotFoundException ex) {
        System.err.println(ex);
    }
    catch (java.io.IOException ex) {
        System.err.println(ex);
    }
    finally {
        try {
            if (zip != null) {
                zip.close();
            }
        }
        catch (IOException ex) {
            System.err.println(ex);
        }
    }
    return fileNames;
}

To use the getFileList() method you might do something like this:

List<String> fileNames = getFilesList("C:\\MyDataFolder", 3, ".cer", ".jar");

// Display files in fileNames List
for (String str : fileNames) {
    System.out.println(str);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.