Short Version
How do i do the equivalent of the hypothetical syntax:
import plugin.jar.netscape.javascript.JSObject; //import netscape.javascript.JSObject from plugin.jar
Long Version
I am trying to use a certain class in the Java Class Library:
- Package:
netscape.javascript
- Class:
netscape.javascript.JSObject
- Documentation: https://www.oracle.com/webfolder/technetwork/java/plugin2/liveconnect/jsobject-javadoc/netscape/javascript/JSObject.html#getWindow(java.applet.Applet)
So normally you would call:
import netscape.javascript.JSObject;
and that would be the end of it.
But Java has multiple implementations of JSObject
But there's a bug in the standard Java libraries; there's another implementation of JSObject:
- Package:
netscape.javascript
- Class:
netscape.javascript.JSObject
- Documentation: https://docs.oracle.com/javafx/2/api/netscape/javascript/JSObject.html
In other words:
Library | Package | Class |
---|---|---|
plugin.jar | netscape.javascript | netscape.javascript.JSObject |
jfxrt.jar | netscape.javascript | netscape.javascript.JSObject |
Which means we now have two implementations of netscape.javascript.JSObject
:
- Implementation 1:
plugin.jar/netscape/javascript/JSObject
- Implementation 2:
jfxrt.jar/netscape/javascript/JSObject
Normally this wouldn't be a problem. Any ("built-in") java library is allowed to export the same package and same class as other ("built-in") java library.
But Java bug
The problem is that Implementation 2 - the one in jfxrt.jar
(JavaFX) has some bugs. 1, 2, 3, 4, 5, 6 (i.e. they forgot to implement a method)
So in the .java
code file i'm looking at, for this one import, i need to force the use of Implementation 1 of JSObject - the one that doesn't have the bugs.
Except the following hypothetical syntax doesn't work:
import plugin.jar.netscape.javascript.JSobject
Note: Even if i knew how to exclude certain Java libraries from a project, doesn't mean that there isn't code elsewhere that requires the Implementation 2.
Research Effort
I started by deleting every copy of jfxrt.jar
i could find on my PC (rip SmartSVN, Minecraft, Aqua Data Studio, SmartSVN-portable, Java 1.8), but the Java compiler kept finding the buggy version of JSObject.
I tried to View Definition of the JSObject class, and it conjures up a code file from somewhere, that definitely has the bugs:
I've tried using Process Monitor to try to spy on every file access to a file that contains the words:
- jfxrt.jar
- jfxrt
- JSObject
- netscape
in order to figure out where this buggy implementation of JSObject is coming from; but there is none. I get the impression that the Java runtime might not ship with hundreds of individual .jar
files, but instead have them lumped into a larger distributable file.
Regardless of where it comes from:
- given the situation where the Java Class Library has two competing implementations of a class
- how do i force the import of one particular implementation
- rather than letting Java's equivalent of the Fusion Loader to find the one that it happened to stumble across first?
Alternative Question
When i press F12 in Visual Studio Code to view the declaration of a built-in class, where is it getting that code from? If i can figure out where the code comes from, it might help me ask the next question on Stackoverflow.
Bonus Reading
- Why is getWindow() not able to be resolved?
- Not able to resolve JSObject in a java applet project
- JSObject.getWindow(this); always throws an exception
- Not able to resolve JSObject in a java applet project
Workaround
The only workaround i have for now is to break the system:
/*
* There's a bug in Java. There are two implmentations of netscape.javascript.JSObject:
* - plugin.jar/netscape.javascript.JSObject
* - jfxrt.jar/netscape.javascript.JSObject
*
* The 2nd one has a WONTFIX bug (https://stackoverflow.com/q/72818274/12597)
*
* Which means we need to force the use of the implementation in plugin.jar.
* But Java has no way to force to use of a specific class.
* So we have no choice but to not use it.
*/
private JSObject jsWindow;
// jsWindow = JSObject.getWindow(this);
jsWindow = null; //i hope this feature wasn't important