Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile Java code without dependencies [duplicate]

I have the source for a java program, but I don't have it's dependencies. Is it possible to compile Java code that uses fields, classes and methods that can't be resolved? If not, is there a program or Eclipse plugin that will automatically generate fake classes, variables and methods that can't be resolved during the compilation? Please give examples.

public class Main {
    public static void main(String[] args) {
        // ...
        UnknownClass.unknownMethod();
    }
}

I want it to automatically generate the Class UnknownClass with a method unknownMethod():

public class UnknownClass {
    public static void unknownMethod() {}
}

But not export it in the output .jar

like image 960
Victor2748 Avatar asked Jul 14 '14 00:07

Victor2748


1 Answers

Is it possible to compile Java code that uses fields, classes and methods that can't be resolved?

No. The static dependencies for your source code must all be available at compile time.

If not, is there a program or Eclipse plugin that will automatically generate fake classes, variables and methods that can't be resolved during the compilation?

AFAIK, No.

In fact, I think that it is technically impossible to build such a program. It would entail inferring signatures for classes and methods that we don't have any information about. I don't think it is possible to do that accurately; i.e. accurately enough that the signatures would match the actual signatures of the real classes.

(Some of the problems that would need to be resolved are inferring the correct supertypes for classes, inferring the correct types for arguments and results of methods, inferring whether a method has varargs, inferring whether a method exists with overloads, and so on. Some of these problems are tractable, some are definitely not.)


But how did Bukkit did it with CraftBukkit.jar and Bukkit.jar? in Bukkit.jar, there are the method headers with no inner code, however when compiling your code for BUkkit.jar, it works with Craftbukkit.jar.

I think you have answered your own question. The class hierarchy and the method headers are in the Bukkit JAR file that is provided. Therefore, they don't need to be inferred.

By contrast, what you are asking to do here is to infer the classes hierarchy and method signatures from a clean slate ... plus some constraints implied by the code (your source code) that uses them.


Here is an example:

   UnknownClass c = ...
   c.method(42);
   c.method(42.0);

There are multiple different solutions to that:

   public class UnknownClass ... {
       void method(double arg) {...}
   }

   public class UnknownClass ... {
       int method(double arg) {...}
   }

   public class UnknownClass ... {
       void method(int arg) {...}
       void method(double arg) {...}
   }

   public class UnknownClass ... {
       void method(byte arg) {...}
       void method(double arg) {...}
   }

   public class UnknownClass ... {
       void method(double... arg) {...}
   }

and so on.

Question: Which is the correct one; i.e. the one that is going to match the actual signatures in the real UnknownClass?

Answer: We have no way of knowing! And it DOES matter, because if we get it wrong there are likely to be classloader errors when you attempt to run the compiled code against the JAR containing the real class.

like image 148
Stephen C Avatar answered Sep 29 '22 23:09

Stephen C