首页 > 解决方案 > java.lang.StringIndexOutOfBoundsException:更改包名时字符串索引超出范围

问题描述

我想从放置在随机文件夹中的 .class 文件中读取注释。我试过这个:

            public static void main(String[] args) throws Exception
            {    
                final File folder = new File("/opt/test");
                processAnnotatedFiles(listLocalFilesAndDirsAllLevels(folder));

            }

        public void processAnnotatedFiles(List<File> list) throws IOException, ClassNotFoundException {
            out.println("Directory files size " + list.size());

            for(int i=0; i<list.size(); i++) {
                out.println("File " + list.get(i).getName());

                File file = list.get(i);

                String path = file.getPath();

                String[] authors = getFixFromClassFile(Paths.get(path));
                System.out.println(Arrays.toString(authors));
            }

        }

        public List<File> listLocalFilesAndDirsAllLevels(File baseDir) {

            List<File>  collectedFilesAndDirs = new ArrayList<>();
            Deque<File> remainingDirs = new ArrayDeque<>();

            if(baseDir.exists()) {
                remainingDirs.add(baseDir);

                while(!remainingDirs.isEmpty()) {
                    File dir = remainingDirs.removeLast();
                    List<File> filesInDir = Arrays.asList(dir.listFiles());
                    for(File fileOrDir : filesInDir)  {
                        // We need to process only .class files
                        if(fileOrDir.getName().endsWith(".class")){
                            collectedFilesAndDirs.add(fileOrDir);
                            if(fileOrDir.isDirectory()) {
                                remainingDirs.add(fileOrDir);
                            }
                        }
                    }
                }
            }

            return collectedFilesAndDirs;
        }

        private String[] getFixFromClassFile(Path pathToClass) throws MalformedURLException, ClassNotFoundException {
            // Create class loader based on path
            URLClassLoader loader = new URLClassLoader(new URL[]{pathToClass.toUri().toURL()});

            // convert path to class with package
            String classWithPackage = getClassWithPackageFromPath(pathToClass);

            // Load class dynamically
            Class<?> clazz = loader.loadClass(classWithPackage);
            Fix fix = clazz.getAnnotation(Fix.class);
            if (fix == null) {
                return new String[0];
            }

            return fix.author();
        }

        private String getClassWithPackageFromPath(Path pathToClass) {
            final String packageStartsFrom = "com.";
            final String classFileExtension = ".class";
            final String pathWithDots = pathToClass.toString().replace(File.separator, ".");
            return pathWithDots.substring(pathWithDots.indexOf(packageStartsFrom)).replace(classFileExtension, "");
        }

我明白了java.lang.StringIndexOutOfBoundsException: String index out of range: -1 at java.lang.String.substring(String.java:1927)

在这一部分中,我想在随机目录中创建一个包。从路径创建一个有效的包真的很难,因为没有任何规则包名应该遵循。

你能给我一些建议如何解决这个问题吗?

标签: javareflectionannotationsclassloaderdynamic-class-loaders

解决方案


推荐阅读