2017-10-12 50 views
-1

我正在尝试使用Class.forName()加载类,但它给了我异常java.lang.ClassNotFoundException: Test找不到动态加载类

实际上Test是在eclipse工作目录here is the image中创建的,但它创建在bin文件夹之外。 如果我尝试运行使用命令提示符它正常工作。

下面的代码:

public class CompileString { 

public static void main(String arges[]) throws Exception{ 

    JavaCompiler compiler=ToolProvider.getSystemJavaCompiler(); 
    String program = " class Test{" + " public static void main (String [] args){" 
       + "  System.out.println (\"Hello, World\");" 
       + "  System.out.println (args.length);" + " }" + "}" 
       +"interface demo{}"   
       ; 

    Iterable<? extends JavaFileObject> fileObjects; 
     fileObjects = getJavaSourceFromString(program); 

     Boolean result=compiler.getTask(null, null, null, null, null, fileObjects).call(); 
     System.out.println(result); 


     Class<?> clazz=null; 
     try { 
      clazz = Class.forName("Test"); 
     } catch (ClassNotFoundException e) { 
      // TODO Auto-generated catch block 
       System.out.println(clazz); 
      e.printStackTrace(); 

     } 
     Method m = clazz.getMethod("main", new Class[] { String[].class }); 
     Object[] _args = new Object[] { new String[0] }; 
     m.invoke(null, _args); 
     } 

     static Iterable<JavaSourceFromString> getJavaSourceFromString(String code) { 
     final JavaSourceFromString jsfs; 
     jsfs = new JavaSourceFromString("demo", code); 
     return new Iterable<JavaSourceFromString>() { 
      public Iterator<JavaSourceFromString> iterator() { 
      return new Iterator<JavaSourceFromString>() { 
       boolean isNext = true; 

       public boolean hasNext() { 
       return isNext; 
       } 

       public JavaSourceFromString next() { 
       if (!isNext) 
        throw new NoSuchElementException(); 
       isNext = false; 
       return jsfs; 
       } 

       public void remove() { 
       throw new UnsupportedOperationException(); 
       } 
      }; 
      } 
     }; 
     } 

} 

另一类:

class JavaSourceFromString extends SimpleJavaFileObject { 
    final String code; 

    JavaSourceFromString(String name, String code) { 
    super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE); 
    this.code = code; 
    } 

    public CharSequence getCharContent(boolean ignoreEncodingErrors) { 
    return code; 
    } 
} 

它给了我运行时异常

抛出java.lang.ClassNotFoundException:测试

一切工作正常编译器JavaCompiler compiler=ToolProvider.getSystemJavaCompiler()给出true但为什么我无法找到Test.class

+0

类测试是不是在你的classpath – Jens

+0

延..thanx您的回复yest它不是类路径,但我可以解决这个问题 –

+0

如果我尝试运行使用命令提示符它工作正常 –

回答

1

为什么这个代码不工作

Eclipse的产生在不同的目录到程序运行,而当你在命令行中运行它,您使用的是相同的值的一个类文件。

如何解决

来解决,这将是使用的URLClassLoader来加载类最简单的方法,让你可以指定目录用于查找类文件。

示例代码(使用List.of从Java 9)

import java.io.File; 
import java.io.IOException; 
import java.lang.reflect.*; 
import java.net.MalformedURLException; 
import java.net.URI; 
import java.net.URLClassLoader; 
import java.util.*; 
import java.util.logging.Logger; 
import javax.tools.*; 

public final class CompileString { 

    static class JavaSourceFromString extends SimpleJavaFileObject { 
     private final String code; 

     JavaSourceFromString(final String name, final String code) { 
      super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE); 
      this.code = code; 
     } 

     @Override 
     public CharSequence getCharContent(final boolean ignoreEncodingErrors) { 
      return code; 
     } 
    } 

    private CompileString() {} 

    private static final Logger LOG = Logger.getLogger(CompileString.class.getCanonicalName()); 

    private static final JavaCompiler COMPILER = ToolProvider.getSystemJavaCompiler(); 
    public static void main(final String...args) { 

     final String program = 
      "public class Test{" + 
      " public static void main (String [] args) {" + 
      "  System.out.println (\"Hello, World\");" + 
      "  System.out.println (args.length);" + 
      " }" + 
      "}"; 

     final List <JavaSourceFromString> fileObjects = List.of(new JavaSourceFromString("Test", program)); 

     final boolean result = COMPILER.getTask(null, null, null, null, null, fileObjects).call(); 
     LOG.info("Compilation result was: " + result); 

     final URL url; 
     try { 
      url = new File("./").toURI().toURL(); 
     } catch (final MalformedURLException ex) { 
      throw new AssertionError("Bad URL? (Really shouldn't happen)", ex); 
     } 

     try (URLClassLoader loader = new URLClassLoader(new URL[] {url})) { 
      final Class<?> clazz = loader.loadClass("Test"); 
      final Method main = clazz.getMethod("main", String[].class); 
      final Object[] invocationArguments = {new String[] {}}; 
      main.invoke(null, invocationArguments); 
     } catch (final ClassNotFoundException ex) { 
      throw new AssertionError("Bad class name", ex); 
     } catch (final IOException ex) { 
      throw new AssertionError("IO Error", ex); 
     } catch (final NoSuchMethodException ex) { 
      throw new AssertionError("Missing main method", ex); 
     } catch (final IllegalAccessException ex) { 
      throw new AssertionError("Class or main method not public", ex); 
     } catch (final InvocationTargetException ex) { 
      throw new AssertionError("Exception thrown by main method", ex); 
     } 
    } 

} 
+0

jrtapsell thanx的答复有任何示例代码链接,所以我可以解决它? –

+0

只是清理我的示例代码之前,我发布 – jrtapsell

+0

jrtapsell ..感谢兄弟 –