1

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:

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:

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:

enter image description here

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

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
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • 2
    The package `netscape.javascript` is not part of Java's public API, and therefore not a public part of the standard library. What version of Java are you using, and what exactly do you need this for? Note that applets are dead, and modern browsers do not support them anymore. – Jesper Jun 30 '22 at 15:22
  • It's standard enough that trying to export a package named `netscape.javascript` runs afoul of the **Java Platform Module System**, which [disallows 3rd parties from having a package named `netscape.javascript`](https://stackoverflow.com/questions/72807971/how-to-make-a-package-not-accessible-from-a-module-i-e-how-to-remove-a-package) - because Java owns it. Either way: java ships with both implementations, one is buggy, and i need the other one. – Ian Boyd Jun 30 '22 at 15:25
  • Intriguing problem, a suggestion, how about doing a custom class loader which you use while instantiating JSObject (only from plugin) and rest of the class loading from the parent class loader dispatch, which shall prevent the ClassCast. If the same class loader is used from different parts of the program fro the same class, it could work. – Ironluca Jun 30 '22 at 19:49

0 Answers0