0

I am facing the following problem:

I will receive one or more .java files. The idea is to automate the compile and execute process.

  1. I have not written nor viewed .java source files i receive.
  2. There may be 1 file or multiple files in multiple directories.
  3. All of this is done under linux ( Debian / CentOS ).

Here is an example case:

  • 2 files are received:
  • SomeFile.java and SomeOtherFile.Java ( This one has the static public void main(String args[]){} method but i do NOT know that !)
  • A process picks up the files and compiles them in this way: javac -encoding UTF-8 -sourcepath . -d . *.java

So my problem is: I do not know which package(if any) contains the Main method so i do not know what do execute ?

java packageName.SomeOtherFile

2 Answers 2

1

Plenty of ways:

  1. Get a java source code parser, parse the source code, find the method
  2. Compile everything, go over the resulting *.class files using reflection, find the method.
  3. For a small enough number of files, just try them all
Sign up to request clarification or add additional context in comments.

1 Comment

... i ended up just looking @ all the files, and finding out where the package and Main functions are ...
1

I have written something like this before:

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;
        }
    }

}

I have not edited it; you will need to edit it so it loads your own classes. You also need to compile the files first with the JavaCompiler class. This also assumes that the classes are in the zip file.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.