Community
Participate
Working Groups
When compiling more dependencies are checked than needed runtime. Reproduction: Create a class public class UnusedServer { public void doSomething() { System.out.println("UnusedServer is doing something"); } static { System.out.println("Class " + UnusedServer.class.getName() + " loaded"); } } put it in missing.jar create another class public class UsedServer { public void doSomething() { System.out.println("UnusedServer is doing something"); if (Boolean.getBoolean("use.server")) { UnusedServer server = new UnusedServer(); server.doSomething(); } } static { System.out.println("Class " + UsedServer.class.getName() + " loaded"); } } put it in server.jar now create a project with a third class public class Client { public static void main(String[] args) { Client c = new Client(); c.go(); } public void go() { System.out.println("go 1"); UsedServer server = new UsedServer(); server.doSomething(); System.out.println("go 2"); } static { System.out.println("Class " + Client.class.getName() + " loaded"); } } and use only server.jar in this project. compilation will fail although Client.main() can execute safely as long as the system property "use.server" is unset.
Created attachment 1706 [details] e-mail to jdt-core-dev@eclipse.org describing the phenomenon
Could not reproduce... as long as the class UsedServer was compiled successfully when UnusedServer was available, then the class Client can be modified with no problems. I tried placing the Server classes in separate jar files and projects, which were then closed/deleted... the Client class could always be recompiled. If the only reference to a 'missing' type X is from inside a method body of another type in the class file A, we do not try to retrieve X after reading A.
true, i could not create the situation myself with this setting either. the setting was, what i thought was the minimal original situation. i'll go into this again a bit deeper to come up with a scenario suited to check this.
Created attachment 1718 [details] Eclipse project to reproduce the problem
Procedure to reproduce the problem: Import the project. Make a build. Create a run configuration similar to the one provided in folder misc. (important: omit "missing.jar" from the classpath!) This will compile and run. Now remove "missing.jar" from the build classpath and you will see the error. Note: changes against the original scenario are (see included source as well): - UsedServer has UnusedServer as method argument in an unused method - Client inherits UsedServer
The UsedServer class has 2 methods named #doSomething, one takes no arguments and is the one sent by the Client class, the other takes the missing type UnusedServer. Since the Client class is a subclass of UsedServer, the MethodVerifier retrieves all the methods of the superclass UsedServer... which causes us to fail because we cannot find the missing method parameter type UnusedServer. Bob, I don't see us changing our behaviour. We need to verify a type's methods (the type Client in this case) against the methods it inherits. Even if a subtype does not override a method, it can still have problems because multiple supertypes define incompatible method signatures.
Kent, I can understand your position. However, please consider these remarks: - Other compilers (notably the standard compiler from sun) cope with the situtation without failure. A change in the eclipse compiler would surely ease migration of projects. And, I guess you would rather like to see more than fewer projects move to eclipse. - The check could be made switchable. IMHO This would be a good compromise. - Depending on the procedure choosen, a method's signature can be checked without accessing all class files of all types used therein. At least the type name is present in the class file that contains the signature. So not accessing those class files can improve performance and would certainly make this problem go away. As long as only the type name is needed, this check would suffice.
Our current implementation reifies type name as object (bindings) which is why we need to bind the name to its corresponding representation. We might need to be more lazy, so as to cope with code handled by standard compilers as well. However, this might just be a bug in other compilers as well. Need to investigate.
Removing milestone. Should investigate during testpass.
*** Bug 35594 has been marked as a duplicate of this bug. ***
Released changes that use the qualified names of methods' return & parameter types... no longer do we need to find these types. We still need to find exception types to compare compatibility.
*** Bug 36397 has been marked as a duplicate of this bug. ***
*** Bug 36543 has been marked as a duplicate of this bug. ***
Verified.