I have the following code
to iterate over folders and files in the class path and determine the classes and get a field with a ID and print them out to a logger
. This is working fine if I run this code in my IDE, but if I package my project into a JAR
file and this JAR
file into a EXE file with launch4j, I can't iterate over my classes again.
I get the following path if I try to iterate over my classes in the JAR/EXE file:
file:/C:/ENTWICKLUNG/java/workspaces/MyProject/MyProjectTest/MyProjectSNAPSHOT.exe!/com/abc/def
How can I achieve this to iterate over all my classes in my JAR/EXE file?
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)
{
}
}
}
}
You cannot create File objects from arbitrary URLs and use the usual filesystem traversal methods. Now, I'm not sure if launch4j does make any difference, but as for iterating over the contents of plain JAR file, you can use the official 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")) {
// ...
}
}
Above snippet lists all the entries in the JAR file referenced by url
, i.e. files and directories.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With