Iterate over folders in JAR file directly - java

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.

Related

How to get all class on android app running

I just wanna get all class from my android project,someone suggest me to use dexfile,so,I try it.but it can not get all class ,for example,my packagename is "org.zj",I just wanna get some class which name start with "org.zj" but it response me "android.support.xxx" or "android.arch.xxx" .this is my code
public static List<Class> getClasses(Activity activity) {
List<Class> classes = new ArrayList<>();
try {
String packageName = activity.getPackageName();
System.out.println(packageName + " 包名");
//String packageCodePath = activity.getPackageCodePath();
classes.addAll(getClasses(packageName));
} catch (Exception e) {
e.printStackTrace();
}
return classes;
}
public static List<Class> getClasses(String packageName) {
List<Class> classes=new ArrayList<>();
List<DexFile> multiDex = getMultiDex();
for (DexFile df : multiDex) {
classes.addAll(getClassByDexFile(df,packageName));
}
return classes;
}
public static ArrayList<DexFile> getMultiDex() {
BaseDexClassLoader dexLoader = (BaseDexClassLoader) ClassUtil.class.getClassLoader();
Field f = ClassUtil.getField("pathList", "dalvik.system.BaseDexClassLoader");
Object pathList = getObjectFromField(f, dexLoader);
Field f2 = ClassUtil.getField("dexElements", "dalvik.system.DexPathList");
Object[] list = (Object[]) getObjectFromField(f2, pathList);
Field f3 = ClassUtil.getField("dexFile", "dalvik.system.DexPathList$Element");
ArrayList<DexFile> res = new ArrayList<>();
for (int i = 0; i < list.length; i++) {
DexFile d = (DexFile) getObjectFromField(f3, list[i]);
res.add(d);
}
return res;
}
public static List<Class> getClassByDexFile(DexFile dexFile, String packageName) {
List<Class> classes = new ArrayList<>();
DexFile df = dexFile;
//String regExp = "^" + packageName + ".\\w+$";
for (Enumeration iter = df.entries(); iter.hasMoreElements(); ) {
String className = (String) iter.nextElement();
System.out.println(className + "");
if (className.contains(packageName)) {
try {
classes.add(Class.forName(className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
return classes;
}

use array output in other class

Good day!
I have a method which returns me an array of report names
System.out.println(bc[i].getDefaultName().getValue()
i want to use array output in other class, how i need to linked method outpud in my array in other class?
Method is:
public class ReoprtSearch {
public void executeTasks() {
PropEnum props[] = new PropEnum[] { PropEnum.searchPath, PropEnum.defaultName};
BaseClass bc[] = null;
String searchPath = "//report";
//searchPath for folder - //folder, report - //report, folder and report - //folder | //report
try {
SearchPathMultipleObject spMulti = new SearchPathMultipleObject(searchPath);
bc = cmService.query(spMulti, props, new Sort[] {}, new QueryOptions());
} catch (Exception e) {
e.printStackTrace();
return;
}
if (bc != null) {
for (int i = 0; i < bc.length; i++) {
System.out.println(bc[i].getDefaultName().getValue();
}
}
}
}
array in what i want put the array looks like:
String [] folders =
my trying like:
ReoprtSearch search = new ReoprtSearch();
String [] folders = {search.executeTasks()};
Returns me an error: cannot convert from void to string
Give me an explanations to understand how i can related to method output from other class.
Thanks
The problem is that your executeTasks method doesn't actually return anything (which is why it's void), and just prints to stdout. Instead of printing, add the names to an array and then return it. Something like this:
public class ReoprtSearch {
public String[] executeTasks() {
PropEnum props[] = new PropEnum[] { PropEnum.searchPath, PropEnum.defaultName};
BaseClass bc[] = null;
String searchPath = "//report";
//searchPath for folder - //folder, report - //report, folder and report - //folder | //report
try {
SearchPathMultipleObject spMulti = new SearchPathMultipleObject(searchPath);
bc = cmService.query(spMulti, props, new Sort[] {}, new QueryOptions());
} catch (Exception e) {
e.printStackTrace();
return null;
}
if (bc != null) {
String results[] = new String[bc.length];
for (int i = 0; i < bc.length; i++) {
results[i] = bc[i].getDefaultName().getValue();
}
return results;
}
return null;
}
}

List all files in resources directory in java project

I want to list all files in resources classpath ,I used the following code but get null exception in fList
String path = request.getSession().getServletContext().getRealPath("/resources/rules");
File directory = new File(path);
File[] fList = directory.listFiles();
for (File file : fList){
if (file.isFile()){
System.out.println(file.getName());
}
}
Here is a working example:
https://github.com/bleujin/aradon/blob/master/src/net/ion/nradon/helpers/ClassloaderResourceHelper.java#L30
public static Iterable<FileEntry> listFilesRelativeToClass(Class<?> clazz, String subdirectory) throws IOException {
ArrayList<FileEntry> list = new ArrayList<FileEntry>();
CodeSource src = clazz.getProtectionDomain().getCodeSource();
if (src == null) {
return list;
}
URL classpathEntry = src.getLocation();
try {
// Check if we're loaded from a folder
File file = new File(new File(classpathEntry.toURI()), subdirectory);
if (file.isDirectory()) {
return fileEntriesFor(file.listFiles());
}
} catch (URISyntaxException e) {
// Should never happen, because we know classpathentry is valid
throw new RuntimeException(e);
}
// We're not in a folder, so we must be in a jar or similar
subdirectory = subdirectory.replace(File.separatorChar, '/');
if (!subdirectory.endsWith("/")) {
subdirectory = subdirectory + "/";
}
ZipInputStream jarStream = new ZipInputStream(classpathEntry.openStream());
ZipEntry zipEntry;
while ((zipEntry = jarStream.getNextEntry()) != null) {
if (isChild(subdirectory, zipEntry.getName())) {
String basename = zipEntry.getName().substring(subdirectory.length());
int indexOfSlash = basename.indexOf('/');
if (indexOfSlash < 0 || indexOfSlash == basename.length() - 1) {
list.add(new FileEntry(basename));
}
}
}
return list;
}
private static boolean isChild(String parent, String name) {
return name.startsWith(parent);
}
public static Iterable<FileEntry> fileEntriesFor(File[] files) {
List<FileEntry> fileEntries = new ArrayList<FileEntry>(files.length);
for (File file : files) {
String filename = file.getName();
if (file.isDirectory()) {
filename += "/";
}
fileEntries.add(new FileEntry(filename));
}
return fileEntries;
}
}
How about this source code?
String[] resoures = srcDir.list( new java.io.FilenameFilter()
{
public boolean accept( File dir, String name )
{
String[] extensions = { ".png", ".jar", ".txt" };
String fileName = name.toLowerCase( Locale.getDefault() );
for ( int i = 0; i < extensions.length; i++ )
{
if ( fileName.endsWith( extensions[i] ) )
{
return true;
}
}
return false;
}
} );
Full source here:
http://code.openhub.net/file?fid=kpl9VrAT-CHXE496rmMP8Jbzo5U&cid=y9kXCqEmUoY&s=List%20all%20files%20in%20resoures%20directory%20in%20java%20project&pp=0&fl=Java&ff=1&projSelected=false&filterChecked,=true&mp,=1&mp=1&ml=1&me=1&md=1#L64

Searching Code Unable To Search Audio and Video Files

I have developed a desktop based searching project in java. I have recursively called the search function for searching operation.
My project is working well but it is unable to search in names of audio and video files.
I am putting my code of searching
public void searchFiles(String mainPath, String searchText){
mainFile = new File(mainPath);
System.out.append(mainFile.getAbsolutePath());
File[] roots = mainFile.listFiles();
Arrays.sort(roots);
for (int i = 0; i < roots.length; i++) {
try {
System.out.println(roots[i]);
SearchProgram searchProgram = new SearchProgram(roots[i], searchText);
} catch (Exception exception) {
}
}
}
-----------------------------------------------------------------------------------
class SearchProgram extends Thread {
File fileDir;
String fileName;
public SearchProgram(File d, String n) {
fileDir = d;
fileName = n;
this.start();
}
// this is a recursive file search function
#Override
public void run() {
if (check) {
try {
search(fileDir, fileName);
} catch (Exception exception) {
}
}
}
private void search(File dir, String name) {
if (check) {
String dirPath = dir.getAbsolutePath();
if (dirPath.length() > 60) {
lblCurrentLocation.setText("\\\\.............." + dirPath.substring(60, dirPath.length()));
} else {
lblCurrentLocation.setText(dirPath);
}
if (dir.getName().toLowerCase().endsWith(name.toLowerCase())) {
tableModel.addRow(new Object[]{dir.getAbsolutePath()});
} else if (dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
search(new File(dir, children[i]), name);
}
}
}
}
}
please suggest what is the problem with this code

Listing classes in a package's subdirectory

I'm not sure if I'm using the correct terminology here.. but if my package name is set up like this:
com.example.fungame
-ClassA
-ClassB
-com.example.fungame.sprite
-ClassC
-ClassD
How can I programmatically get an array (a Class[] I'm guessing) of all the classes in the .sprite subdirectory?
Try this method:
public static Class[] getClasses(String pckgname) throws ClassNotFoundException {
ArrayList classes=new ArrayList();
File directory = null;
try {
directory = new File(Thread.currentThread().getContextClassLoader().getResource(pckgname.replace('.', '/')).getFile());
} catch(NullPointerException x) {
throw new ClassNotFoundException(pckgname + " does not appear to be a valid package");
}
if (directory.exists()) {
// Get the list of the files contained in the package
String[] files = directory.list();
for (int i = 0; i < files.length; i++) {
// we are only interested in .class files
if(files[i].endsWith(".class")) {
// removes the .class extension
try {
Class cl = Class.forName(pckgname + '.' + files[i].substring(0, files[i].length() - 6));
classes.add(cl);
} catch (ClassNotFoundException ex) {
}
}
}
} else {
throw new ClassNotFoundException(pckgname + " does not appear to be a valid package");
}
Class[] classesA = new Class[classes.size()];
classes.toArray(classesA);
return classesA;
}

Categories

Resources