编译并执行java源代码而不知道Main方法在哪里?

时间:2014-03-29 13:14:11

标签: java compilation

我遇到以下问题:

我将收到一个或多个.java文件。我们的想法是自动化编译和执行过程。

  1. 我没有写过或查看我收到的.java源文件。
  2. 多个目录中可能有1个文件或多个文件。
  3. 所有这些都是在linux(Debian / CentOS)下完成的。
  4. 以下是一个示例案例:

    • 收到2个文件:
    • SomeFile.java和SomeOtherFile.Java(这个有静态public void main(String args []){} 方法,但我不知道!
    • 进程获取文件并以这种方式编译它们: javac -encoding UTF-8 -sourcepath。 -d。 *的.java

    所以我的问题是:我不知道哪个包(如果有的话)包含Main方法所以我不知道执行了什么?

    java packageName.SomeOtherFile
    

2 个答案:

答案 0 :(得分:1)

有很多方法:

  1. 获取a java source code parser,解析源代码,找到方法
  2. 编译所有内容,使用反射查看生成的* .class文件,找到方法。
  3. 对于足够少的文件,只需尝试所有文件

答案 1 :(得分:1)

我之前写过类似的东西:

package vonbulow.nicki;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 *
 * @author Nicki
 */
public class AppLoader extends ClassLoader {

    private static final String userdir = System.getenv("USERPROFILE");
    private static final AppLoader instance = new AppLoader();

    private static HashMap<String, Class> loaded = new HashMap<String, Class>();

    public static void loadapp(final String name) {

        if(loaded.containsKey(name)) {
            Thread d = new Thread(new Runnable(){
                public void run(){
                    try {
                        Class c = loaded.get(name);
                        Method m = c.getDeclaredMethod("main", String[].class);
                        m.invoke(null, (Object[])new String[]{null});
                    } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {

                    }
                }
            });
            d.start();
            return;
        }

        File ud = new File(userdir+"\\nvbapp");
        ud.mkdir();
        File[] fa = ud.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".appn");
            }
        });

        for(final File f:fa) {
            if(f.getName().split("\\.")[0].equalsIgnoreCase(name)) {
                Thread t = new Thread(new Runnable() {
                    public void run() {
                        runapp(f, name);
                    }
                });
                t.start();
            }
        }
    }

    private static void runapp(File f, String nam) {

        List<Class> classes = new ArrayList<Class>();
        ZipFile jf;
        String name = "";
        try {
            jf = new ZipFile(f);
            Enumeration<? extends ZipEntry> eze = jf.entries();
            while(eze.hasMoreElements()){
                ZipEntry ze = eze.nextElement();
                if(ze.getName().endsWith(".class")&&!ze.isDirectory()){
                    InputStream fis = jf.getInputStream(ze);
                    byte[] bytes = new byte[(int)ze.getSize()];
                    fis.read(bytes);
                    classes.add(instance.defineClass(getClassName(bytes), bytes, 0, bytes.length));
                }
                if(ze.getName().equalsIgnoreCase("META-INF/MANIFEST.MF")) {
                    Manifest manifest = new Manifest(jf.getInputStream(ze));
                    name = manifest.getMainAttributes().getValue("Main-Class");
                }
            }
            Iterator<Class> classit = classes.iterator();
            while(classit.hasNext()) {
                Class c = classit.next();
                if(c.getName().equals(name)) {
                    try {
                        loaded.put(nam, c);
                        Method m = c.getDeclaredMethod("main", String[].class);
                        m.invoke(null, (Object[]) new String[]{null});
                    } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(AppLoader.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private static String getClassName(byte[] is) {
        try {
            DataInputStream dis = new DataInputStream(new ByteArrayInputStream(is));
            dis.readLong(); // skip header and class version
            int cpcnt = (dis.readShort()&0xffff)-1;
            int[] classes = new int[cpcnt];
            String[] strings = new String[cpcnt];
            for(int i=0; i<cpcnt; i++) {
                int t = dis.read();
                if(t==7) classes[i] = dis.readShort()&0xffff;
                else if(t==1) strings[i] = dis.readUTF();
                else if(t==5 || t==6) { dis.readLong(); i++; }
                else if(t==8) dis.readShort();
                else dis.readInt();
            }
            dis.readShort(); // skip access flags
            return strings[classes[(dis.readShort()&0xffff)-1]-1].replace("/", ".");
        } catch (IOException ex) {
            return null;
        }
    }

}

我没有编辑过它;你需要编辑它,以便加载你自己的类。 您还需要首先使用JavaCompiler类编译文件。这也假定类在zip文件中。