Hi,

I'd like to follow up on https://bugs.openjdk.org/browse/JDK-8350547.

TL;DR java.lang.ClassLoader.definePackage() (the one taking 8 arguments) clearly defines that a IllegalArgumentException is thrown, "if a package of the given name is already defined by this class loader".

However, it seems that it's a common oversight that an IAE can be thrown. Examples are the CDI reference implementation ("Weld") and Quarkus. In other words: "naively" calling 'definePackage' without a retry on IAE leads to issues when defining classes in custom class loaders in parallel.

The CL.definePackage() API is there since Java 1.2, and I admit that my initial approach to change the currently observed behavior isn't going to fly.

I thought about adding more information to the message of the IAE thrown in 'definePackage()', but even this "innocent" change could break the observed behavior / existing code.

One option could be to add a new function 'definePackageIfNotExists()` to j.l.ClassLoader, which works like the existing 'definePackage()' but returns the existing package, if it already exists and is compatible with the given arguments. The downside is that it could still throw, if the arguments are incompatible (e.g. a different "implTitle") - so it might just be a less likely, but still possible way of unexpectedly hitting an IAE.

With 'definePackageIfNotExists()` it might be possible to deprecate 'definePackage()', but that deprecation largely depends on the actual usage of it in the wild, which I do not know. I'm not sure whether such a deprecation can fly. And the next question would be whether it can be deprecated for removal ; and if yes, when could it be removed.

Actually, even a new 'definePackageIfNotExists()` could break existing code, in case an implementation overrides the existing 'definePackage' but not 'definePackageIfNotExists()`.

Another question to which I don't know the answer is whether the 7 package attribute parameters specification/implementation title/version/vendor + seal-base do fit "all today's wishes & needs". Or: is there demand for a "better" or "more flexible" way to define a class/package? Or: can that API be redefined in a different way tailored for today's needs and wishes? And are there any that would justify such an effort?

Overall, I'm a bit lost on what the "best" way would be for this. Maybe the answer is that there is no better way yet, which is also fine. Maybe the only "fix" is to enhance the Javadocs and prominently highlight the behavior and add a "reference code snippet" how 'definePackage()' should be used and why.

Robert

--
Robert Stupp
@snazy

Reply via email to