on
Italy
- Get link
- X
- Other Apps
.jar
extension.
The implication of this is that while one can change the name of a JAR
located in a classpath directory to have an extension other than .jar
so that the wildcard does not pick it up, this technique will not work with the extension directory.
HelloWorld
class and a main application class called Main
that uses theHelloWorld
class.
public class HelloWorld
{
@Override
public String toString()
{
return "Hello, World!";
}
}
import static java.lang.System.out;
public class Main
{
public static void main(final String[] arguments)
{
out.println(new HelloWorld());
}
}
To demonstrate a primary difference between classpath and the extension mechanism (optional packages), I will archive the compiled HelloWorld.class
file into a JAR called HelloWorld.jar
and place it in a different directory than the compiled Main.class
file.
To demonstrate the use of the traditional classpath, I place the HelloWorld.jar
file in a directory calledC:\hello
and will access that JAR via wildcard (*) for Main
to use. This is demonstrated in the next two screen snapshots.
Main
application can still load the HelloWorld.class
file even though I had deleted it from the current directory because the Java launcher was explicitly told (via the -classpath
option) to look for it in C:\hello
.
Using the extensions mechanism (optional packages), it is possible to
have the class loaded without it being in the same directory and without
explicit classpath specification. This is shown in the next screen
snapshot.
HelloWorld.class
in
the same directory or specified on its classpath when that class is
inside a JAR that is in the extensions (optional packages) directory.
This is often cited as a benefit of using the extensions mechanism because
all applications using that JRE (or potentially all applications on the
host) can see the same classes without need to explicitly specify them
on the classpath.
.class
file needs to end with the .jar
extension. The next screen snapshot demonstrates what happens when the HelloWorld.jar
is renamed HelloWorld.backup
in the same classpath-referenced directory.
.jar
extension.
Perhaps a bit surprisingly, the extensions (optional packages)
mechanism does not work the same way. Instead, all JAR files in the
extensions specified directory are loaded regardless of their extension
and regardless of even if they have a file extension. This is
demonstrated in the next screen image.
NoSuchMethodError
,
but forgotten outdated and obsolete class definitions residing inside
of JAR files in the extensions directory are another potential cause.
This is demonstrated next.
Main.java
and HelloWorld.java
. In particular,HelloWorld
has an all-new method that the new version of Main
invokes. In this case, I'm going to leave the newly compiled HelloWorld.class
file in the same directory when I run the Main
to demonstrate that the old, busted version of HelloWorld.class
in the JAR in the extensions directory takes precedence over the new hotness HelloWorld.class
in the current directory.
public class HelloWorld
{
@Override
public String toString()
{
return "Hello, World!";
}
public String directedHello(final String name)
{
return "Hello, " + name;
}
}
import static java.lang.System.out;
public class Main
{
public static void main(final String[] arguments)
{
final HelloWorld helloWorld = new HelloWorld();
out.println(helloWorld);
out.println(helloWorld.directedHello("Dustin"));
}
}
The last image demonstrates that the now obsolete class definition of HelloWorld
in the extensions directory takes precedence over the new class definition of HelloWorld
in
the same directory. Even when I specify the current directory on the
classpath, the old version in the extensions directory takes precedence.
This is shown in the next screen snapshot, which also shows that the
JAR in the extensions directory that is "hiding" the newer JAR and its
class's newer method is still not even named with a .jar
extension.
NoSuchMethodError
to
alert me to a problem. A potentially even more difficult situation to
debug can exist when the old class definition has the same method
signature but has an outdated method implementation. In such cases,
there may be no error, exception, or throwable of any kind, but the
application logic will simply not work correctly or as expected. The old
functionality could exist in the code base for some time before it's
even recognized as an issue, especially if unit tests and other testing
is lacking.
.jar
file
extensions) that reside in the directory referenced as an extension
directory will be loaded. Renaming these JARs and even changing their
file extension will not be sufficient to have the classloading ignore
them. With classpath, on the other hand, renaming the JAR is sufficient
to prevent loading when the classpath specifies individual JAR files
explicitly and changing the file extension is typically sufficient to
prevent loading even when the classpath uses the wildcard (*) to specify
all JARs in a directory.
NoSuchMethodError
s so that one can check it out to see if the offender lives in that directory or directories.