2013-07-02 29 views
1

我有以下code来遍历类路径中的文件夹和文件,并确定类并获取带ID的字段并将它们打印到logger。如果我在我的IDE中运行此代码,这是工作正常,但如果我将我的项目打包到一个JAR文件和此JAR文件到一个EXE文件与launch4j,我不能迭代我的班再次。 我碰到下面的路径,如果我尝试我的班遍历在JAR/EXE文件:直接对JAR文件中的文件夹进行迭代

file:/C:/ENTWICKLUNG/java/workspaces/MyProject/MyProjectTest/MyProjectSNAPSHOT.exe!/com/abc/def 

我怎样才能做到这一点遍历我在我的JAR/EXE文件的所有类?

public class ClassInfoAction extends AbstractAction 
{ 
    /** 
    * Revision/ID of this class from SVN/CVS. 
    */ 
    public static String ID = "@(#) $Id ClassInfoAction.java 43506 2013-06-27 10:23:39Z $"; 

    private ClassLoader classLoader = ClassLoader.getSystemClassLoader(); 
    private ArrayList<String> classIds = new ArrayList<String>(); 
    private ArrayList<String> classes = new ArrayList<String>(); 
    private int countClasses = 0; 

    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
    countClasses = 0; 
    classIds = new ArrayList<String>(); 
    classes = new ArrayList<String>(); 

    getAllIds(); 

    Iterator<String> it = classIds.iterator(); 

    while (it.hasNext()) 
    { 
     countClasses++; 
     //here I print out the ID 
    } 
    } 

    private void getAllIds() 
    { 
    String tempName; 
    String tempAbsolutePath; 

    try 
    { 
     ArrayList<File> fileList = new ArrayList<File>(); 
     Enumeration<URL> roots = ClassLoader.getSystemResources("com"); //it is a path like com/abc/def I won't do this path public 
     while (roots.hasMoreElements()) 
     { 
     URL temp = roots.nextElement(); 
     fileList.add(new File(temp.getPath())); 
     GlobalVariables.LOGGING_logger.info(temp.getPath()); 
     } 

     for (int i = 0; i < fileList.size(); i++) 
     { 
     for (File file : fileList.get(i).listFiles()) 
     { 
      LinkedList<File> newFileList = null; 
      if (file.isDirectory()) 
      { 
      newFileList = (LinkedList<File>) FileUtils.listFiles(file, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE); 

      if (newFileList != null) 
      { 
       for (int j = 0; j < newFileList.size(); j++) 
       { 
       tempName = newFileList.get(j).getName(); 
       tempAbsolutePath = newFileList.get(j).getAbsolutePath(); 
       checkIDAndAdd(tempName, tempAbsolutePath); 
       } 
      } 
      } 
      else 
      { 
      tempName = file.getName(); 
      tempAbsolutePath = file.getAbsolutePath(); 
      checkIDAndAdd(tempName, tempAbsolutePath); 
      } 
     } 
     } 

     getIdsClasses(); 
    } 
    catch (IOException e) 
    { 
    } 
    } 

    private void checkIDAndAdd(String name, String absolutePath) 
    { 
    if (name.endsWith(".class") && !name.matches(".*\\d.*") && !name.contains("$")) 
    { 
     String temp = absolutePath.replace("\\", "."); 
     temp = temp.substring(temp.lastIndexOf(/* Class prefix */)); //here I put in the class prefix 
     classes.add(FilenameUtils.removeExtension(temp)); 
    } 
    } 

    private void getIdsClasses() 
    { 
    for (int i = 0; i < classes.size(); i++) 
    { 
     String className = classes.get(i); 

     Class<?> clazz = null; 
     try 
     { 
     clazz = Class.forName(className); 

     Field idField = clazz.getDeclaredField("ID"); 
     idField.setAccessible(true); 

     classIds.add((String) idField.get(null)); 
     } 
     catch (ClassNotFoundException e1) 
     { 
     } 
     catch (NoSuchFieldException e) 
     { 
     } 
     catch (SecurityException e) 
     { 
     } 
     catch (IllegalArgumentException e) 
     { 
     } 
     catch (IllegalAccessException e) 
     { 
     } 

    } 
    } 
} 
+0

你已经导入的你需要的类需要在你运行这个jar之前先加载到classpath中。希望你没有错过它 – mitpatoliya

+0

我不明白你的意思吗?我需要做什么? –

+0

如果您使用Java 7,它就像'Filesystems.newFileSystem(“/ path/to/the/jar”)一样简单。然后你可以使用'Filesystem' /'Path'的所有优点。 – fge

回答

3

您不能从任意URL创建File对象并使用通常的文件系统遍历方法。现在,我不知道如果没有launch4j任何区别,但作为迭代普通JAR文件的内容,你可以使用官方API:

JarURLConnection connection = (JarURLConnection) url.openConnection(); 
JarFile file = connection.getJarFile(); 
Enumeration<JarEntry> entries = file.entries(); 
while (entries.hasMoreElements()) { 
    JarEntry e = entries.nextElement(); 
    if (e.getName().startsWith("com")) { 
     // ... 
    } 
} 

上面的代码中列出了JAR文件中的所有条目由url引用,即文件和目录。