Results 1 to 10 of 10
  1. #1
    K1kk0z90 is offline Member
    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0

    Question Problems listing methods using Reflection

    Hi all! :)

    I'm trying to make a simple program in Java that, given as command line argument a directory, it prints to standard output the list of methods for each .class file inside the given directory.
    But I get a ClassNotFoundException when using the Class.forName() method. Could someone please help me understand what I'm doing wrong in my code? Here's my code:

    Java Code:
    import java.lang.reflect.*;
    import java.util.Collection;
    import java.io.*;
    
    import org.apache.commons.io.*;
    import org.apache.commons.io.filefilter.FileFilterUtils;
    import org.apache.commons.io.filefilter.TrueFileFilter;
    
    public class ListMethods {
    	public static void main(String[] args) {
    		if (args.length != 1) {
    			System.out.println("Invalid number of arguments.");
    			return;
    		}
    		
    		// The directory in which to look for all .class files.
    		File rootDir = new File(args[0]);
    		if (!rootDir.isDirectory()) {
    			System.out.println("Invalid argument. You must pass the root directory in which all .class files reside.");
    			return;
    		}
    				
    		// Get all .class files.
    		Collection<File> classFiles = FileUtils.listFiles(rootDir, 
    				FileFilterUtils.suffixFileFilter(".class"),
    				TrueFileFilter.INSTANCE);
    		
    		// For each .class file, get a list of all its methods.
    		for (File classFile : classFiles) {
    			String className = classFile.getName().substring(0,
    					classFile.getName().length() - ".class".length());
    			
    			try {
    				@SuppressWarnings("rawtypes")
    				Class theClass = Class.forName(className); // !!! ClassNotFoundException !!!
    				Method[] methods = theClass.getDeclaredMethods();
    				
    				// Print all the methods signatures.
    				for (Method m : methods) {
    					System.out.println(m.toString());
    				}
    			} catch (ClassNotFoundException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    }
    Thank you very much in advanced for your help! :)

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,097
    Rep Power
    20

    Default Re: Problems listing methods using Reflection

    Is that directory on the class path?
    If it isn't then how are you loading the classes in it?
    How do you determine the full class name (including the package)?
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  3. #3
    K1kk0z90 is offline Member
    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0

    Default Re: Problems listing methods using Reflection

    You're right, the directory is not on the class path.
    I modified my code using a URLClassLoader to dynamically change the class path to the .class file.
    Now the problem is that I don't know how to dynamically get the Fully Qualified Name of the class to load. At the moment I'm passing only the class name to the Class.forName() method, so I'm still getting the ClassNotFoundException. Here's my modified code:

    Java Code:
    import java.lang.reflect.*;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLClassLoader;
    import java.util.Collection;
    import java.io.*;
    
    import org.apache.commons.io.*;
    import org.apache.commons.io.filefilter.FileFilterUtils;
    import org.apache.commons.io.filefilter.TrueFileFilter;
    
    public class ListMethods {
    	public static void main(String[] args) {
    		if (args.length != 1) {
    			System.out.println("Invalid number of arguments.");
    			return;
    		}
    		
    		// The directory in which to look for all .class files.
    		File rootDir = new File(args[0]);
    		if (!rootDir.isDirectory()) {
    			System.out.println("Invalid argument. You must pass the root directory in which all .class files reside.");
    			return;
    		}
    				
    		// Get all .class files.
    		Collection<File> classFiles = FileUtils.listFiles(rootDir, 
    				FileFilterUtils.suffixFileFilter(".class"),
    				TrueFileFilter.INSTANCE);
    		
    		// For each .class file, get a list of all its methods.
    		for (File classFile : classFiles) {
    			String className = classFile.getName().substring(0,
    					classFile.getName().length() - ".class".length());
    			
    			try {
    				URL url = classFile.toURI().toURL();
    				URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { url });
    				
    				@SuppressWarnings("rawtypes")
    				Class theClass = Class.forName(className, true, classLoader); // !!! ClassNotFoundException !!!
    				Method[] methods = theClass.getDeclaredMethods();
    				
    				// Print all the methods signatures.
    				for (Method m : methods) {
    					System.out.println(m.toString());
    				}
    			} catch (ClassNotFoundException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			} catch (MalformedURLException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    }
    Thank you again.

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,097
    Rep Power
    20

    Default Re: Problems listing methods using Reflection

    You'll need to figure that out then.
    The user will need to put the root directory in, and then the fully qualified class name.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  5. #5
    K1kk0z90 is offline Member
    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0

    Default Re: Problems listing methods using Reflection

    It's very strange, I've tried to make a very simple version of the program, just as a test, in which I try to get the Class from a specific .class file. I've hardcoded the path to this file. It is a class of the open source project Checkstyle. Looking at the source code of this class, I can see the package declaration, so I also know the Fully Qualified Name of the class. But I still get the ClassNotFoundException when invoking the Class.forName() method. Could you tell me what I'm doing wrong, please?

    Java Code:
    import java.io.*;
    import java.net.*;
    
    /*
     * Just a test: get the Class from this .class file:
     * C:\Users\Federico\Downloads\checkstyle-4.4\checkstyle-4.4\checkstyle-4.4\com\puppycrawl\tools\checkstyle\api\Check.class
     * 
     * The source code of that class, Check.java, reports this package:
     * com.puppycrawl.tools.checkstyle.api
     * and the class file is infact in this path from the project's root directory:
     * /com/puppycrawl/tools/checkstyle/api/Check.class
     * 
     * So the fully qualified name for that class should be:
     * com.puppycrawl.tools.checkstyle.api.Check
     */
    public class ListMethodsSimple {
    	public static void main(String[] args) {
    		String dirPath = "C:\\Users\\Federico\\Downloads\\checkstyle-4.4\\checkstyle-4.4\\checkstyle-4.4\\com\\puppycrawl\\tools\\checkstyle\\api\\";
    		File parentDirectory = new File(dirPath);
    		
    		try {
    			URL url = parentDirectory.toURI().toURL();
    			URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { url });
    			String fullyQualifiedName = "com.puppycrawl.tools.checkstyle.api.Check";
    			
    			Class theClass = Class.forName(fullyQualifiedName, true, classLoader); // ClassNotFoundException
    		} catch (MalformedURLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }
    Thank you again for your help, I really appreciate! :)

  6. #6
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,097
    Rep Power
    20

    Default Re: Problems listing methods using Reflection

    Because you are not adding the root of the class structure in that class loader.
    You are adding the directory that happens to contain the class file...which is several levels below the root.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  7. #7
    K1kk0z90 is offline Member
    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0

    Default Re: Problems listing methods using Reflection

    Sorry, I don't think I understand correctly.
    In the URLClassLoader I have to pass a URL array. In my case I pass an array with just one URL, that is the URL form of the absolute path to the directory that contains the .class file. So it is something like "file:/C:/ ... /api/" where "api" is the directory that directly contains the .class file. Because of the fact it starts from C: , isn't it the root of the structure?
    Then I pass to the Class.forName() method the string made of the package of the package and the name of the class, and it should be the fully qualified name.
    What do you mean saying that I'm not adding the root of the class structure in the class loader? What would be the correct root of it?
    Thank you again.

  8. #8
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,097
    Rep Power
    20

    Default Re: Problems listing methods using Reflection

    What directory would you add to the classpath if you were attempting to run code that included this class file?
    Hint: you would not use the directory containing the class.
    Look at the directory structure and the full class name.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  9. #9
    K1kk0z90 is offline Member
    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0

    Default Re: Problems listing methods using Reflection

    Thank you very much. Now I see what you mean. I've modified my code and now it works! :)

    Java Code:
    import java.io.*;
    import java.net.*;
    
    public class ListMethodsSimple {
    	public static void main(String[] args) {
    		try {
    			URL url = new URL("file:///C:/Users/Federico/Downloads/");
    			URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { url });
    			String fullyQualifiedName = "com.mytest.MyTest";
    			Class theClass = Class.forName(fullyQualifiedName, true, classLoader);
    			System.out.println("All OK!");
    		} catch (MalformedURLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }
    Now I'm going to try again to do what I originally tried to do: get all methods of the classes in a directory. If I need help, I'll post here. :)

  10. #10
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default Re: Problems listing methods using Reflection

    Moved from New to Java

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

Similar Threads

  1. Listing problems
    By Payatola2287 in forum Java Servlet
    Replies: 2
    Last Post: 03-05-2012, 11:00 AM
  2. Class Reflection: Showing methods
    By Java Tip in forum java.lang
    Replies: 0
    Last Post: 04-23-2008, 08:11 PM
  3. Execution methods Reflection
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 11-15-2007, 03:19 PM
  4. Getting methods of a Class - Reflection
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 11-15-2007, 03:18 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •