overloading, third party encapsulation, and compiler classpaths

W

Wayne Berke

Does anyone know where I can find a formal specification that can be used
to determine which classes need to be found on the javac classpath for a
given set of source files?

Clearly, not all classes that need to be loaded at runtime need to be
accessible at compiletime. For example, a precompiled JAR may
encapsulate a number of 3rd party classes but not actually expose them
in its public API. Compiling a source file that limited itself to that
API would then not generally require access to the 3rd party classes.

For example, consider a java archive (call it common.jar) that contains
classes and methods for general use. Consider further that those classes
encapsulate and hide other classes from another archive (called thirdparty.jar).

Now, we want to write a java program Myclass.java that uses the API presented
by common.jar. I would expect that when building common.jar, we would
need to include thirdparty.jar in the javac classpath. However, once
that jar is built, I'd think that compiling Myclass.class would *not*
require thirdparty.jar on its classpath but just common.jar. After all,
the compiler should only need to identify and match the method signatures from
common.jar if a class is limiting itself to that API. And in the general
case, this is exactly true.

However, suppose we want to invoke a method within Common.class that uses
overloading in this way:

public class Common {
public void someMethod(String foo) { ... }
public void someMethod(ThirdPartyClass tpc) { .. }
}

Assuming that ThirdPartyClass is found in thirdparty.jar, I find that
having a call to someMethod(String) within MyClass will result in a compiler
error (can't find ThirdPartyClass) if only common.jar appears on the
classpath. Therefore, you must also include thirdparty.jar in order to
compile it, in spite of the fact that you don't address ThirdPartyClass
directly in the source.

Now, I suppose this makes some sense because the compiler in the course of
matching up the right method signature must consider the second signature
which in turn entails understanding the structure of ThirdPartyClass.

However, what I would think that changing the method signatures to:

public class Common {
public void someMethod(String foo) { ... }
private void someMethod(ThirdPartyClass tpc) { .. }
}

would prevent javac from needing to load ThirdPartyClass, but I find
I get the same error! I don't understand that at all. Why should
the compiler even need to look at the second method signature since
it can't possibly be used from a different class?

The only way to remove the requirement for compiler access to thirdparty.jar
is to avoid overloading altogether:

public class Common {
public void someOtherMethod(String foo) { ... }
public void someMethod(ThirdPartyClass tpc) { .. }
}

Now if I confine myself to using the first method, only common.jar will
be needed on the classpath.

Can anyone shed light on this state of affairs?

BTW, in my tests I'm using the compiler from Sun's 1.3.1 JDK.

Wayne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top