kumuluzee
kumuluzee copied to clipboard
Not possible to introspect the uberJar classpath by resource partial name
It's not currently possible to look for classes on the classpath that reside in the uberJar itself using only their partial names (i.e. name of a package) because of this line in EeClassLoader
: https://github.com/kumuluz/kumuluzee/blob/62f1ea9e6824b67c7b66391a62da165f944bf000/tools/loader/src/main/java/com/kumuluz/ee/loader/EeClassLoader.java#L297.
The introspection works for classes in jars, so a quick solution might be just to move the classes from inside the uberJar to a separate lib jar, but it's an inconvenience; the runtime should not impose such limitations on the project structure.
I wonder if this behaviour is intentional, and if so - what was the intention, and whether the line 297 can be patched with something like if (fileInfo.getSimpleName().startsWith(name)) {
?
PS. Now that i was approved full access to github from office, i can implement a necessary fix, but i'm not ready to commit to core without discussing with you guys first.
I don't think ClassLoader's getResource is supposed to work this way (see: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassLoader.html#getResource(java.lang.String)).
Package scanning is not really supported by ClassLoaders. Classes are loaded dynamically and thus ClassLoader doesn't have to know what packages it provides.
I recommend you use something like https://github.com/classgraph/classgraph instead. There are some specifics concerning Uberjars but we have successfully used the library here: https://github.com/kumuluz/kumuluzee-openapi-mp/blob/a7e3d4b077a4ce9f2aa2590a61f652bc5ae1ebc8/core/src/main/java/com/kumuluz/ee/openapi/mp/OpenApiMpExtension.java#L103.
I saw you using classgraph in there, ok i'll give it a try.
ClassLoader's getResource is supposed to work this way
Actually it does work sort of this way. I just debugged BuiltinClassLoader
from JDK 12, which is the superclass for all classloaders by default, and when #getResources(String)
would be called with something like "com/kumuluz/ee" it will return a URL for this directory, while EeClassLoader
would return nothing.
I think it must behave at least the same way, otherwise it breaks alot of stuff relying on this behaviour. I suggest the issue be reopened.
I mean this is questionable at best. The fix would require a lot of work and testing and may have an impact on performance of KumuluzEE. I don't see enough benefits from this functionality. If you really need this behaviour I suggest you run the application as exploded.
I don't see enough benefits from this functionality
So the fact that by not having this functionality (because you chose to interpret the specification the way that suits you) you break the expected classloader behaviour doesn't bother you at the slightest?
How a classloader is supposed to behave is defined in the javadocs and not by observing behaviour of a JDK classloader of your choice.
I haven't seen anything that relies on the behaviour you describe or heard of any use-case where this would be desirable.
EeClassLoader is a core class for the KumuluzEE implementation and we don't take changes to it lightly. What I'm saying is that we are not prepared to allocate resources to implement this feature or even potentially review a PR proposing an implementation.
How a classloader is supposed to behave is defined in the javadocs
A directory is a resource and so if i wanted to get a reference to a directory relative to the classpath root (which in no way contradics the spec), then the desired behaviour is definitely not present.
haven't seen anything that relies on the behaviour you describe
Spring Framework depends on this very behaviour since 2003.
a JDK classloader of your choice.
Well, if how OpenJDK (which is literally the RI of the JDK spec) behaves is just something you find inconsequential, then there's nothing else i can say.
Oh yes, did i forget to mention that getResources
breaks even what you suggest it does and behaves inconsistently depending on whether the directory is in a jar, or not? In the former case you seem to have no issues with interpreting the spec in a certain way and return a directory URL within a jar.
Do you think that such inconsistent behaviour is also according to the JDK spec?
Ok, we will take a look at it.