Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disabling compile-time dependency checking when compiling Java classes

Consider the following two Java classes:

a.) class Test { void foo(Object foobar) { } }

b.) class Test { void foo(pkg.not.in.classpath.FooBar foobar) { } }

Furthermore, assume that pkg.not.in.classpath.FooBar is not found in the classpath.

The first class will compile fine using the standard javac.

However, the second class won't compile and javac will give you the error message "package pkg.not.in.classpath does not exist".

The error message is nice in the general case since checking your dependencies allows the compiler to tell you if you got some method argument wrong, etc.

While nice and helpful this checking of dependencies at compile-time is AFAIK not strictly needed to generate the Java class file in the example above.

  1. Can you give any example for which it would be technically impossible to generate a valid Java class file without performing compile time dependency checking?

  2. Do you know of any way to instruct javac or any other Java compiler to skip the compile time dependency checking?

Please make sure your answer addresses both questions.

like image 359
knorv Avatar asked Oct 08 '09 13:10

knorv


People also ask

What is checked during compile time?

During compile time the compiler check for the syntax, semantic, and type of the code.

What happens at compile time in Java?

What happens at compile time? At compile time, the Java file is compiled by Java Compiler (It does not interact with OS) and converts the Java code into bytecode.

Where does Javac compile to?

By default, javac compiles each source file to a class file in the same directory as the source file.


2 Answers

I don't think there is such a way - the compiler needs to know about the class of the argument, in order to create appropriate bytecode. If it cannot locate the Foobar class, it cannot compile the Test class.

Note that while your two classes are functionally equivalent since you're not really using the argument, they aren't identical and will yield different bytecode when compiled.

So your premise - that the compiler doesn't need to find the class to compile in this case - is incorrect.

Edit - your comment seems to be asking "can't the compiler just overlook the fact and generate the bytecode that would be appropriate anyway?"

The answer is that no - it can't. According to the Java Language Specification, method signatures must take types, which are elsewhere defined to be resolvable at compile-time.

Which means that while it would be mechanically quite simple to create a compiler that would do what you're asking for, it would violate the JLS and thus wouldn't technically be a Java compiler. Besides, circumventing compile-time safety doesn't sound like a great selling-point to me... :-)

like image 142
Andrzej Doyle Avatar answered Sep 23 '22 15:09

Andrzej Doyle


Can you give any example for which it would be technically impossible to generate a valid Java class file without performing compile time dependency checking?

Consider this code:

public class GotDeps {
  public static void main(String[] args) {
    int i = 1;
    Dep.foo(i);
  }
}

If the target method has the signature public static void foo(int n), then these instructions will be generated:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_1
   2:   iload_1
   3:   invokestatic    #16; //Method Dep.foo:(I)V
   6:   return

If the target method has the signature public static void foo(long n), then the int will be promoted to a long prior to the method invocation:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_1
   2:   iload_1
   3:   i2l
   4:   invokestatic    #16; //Method Dep.foo:(J)V
   7:   return

In this case, it would not be possible to generate the invocation instructions or how to populate the CONSTANT_Methodref_info structure referred to in the class constant pool by the number 16. See the class file format in the VM spec for more details.

like image 26
McDowell Avatar answered Sep 25 '22 15:09

McDowell