Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not possible to introspect the uberJar classpath by resource partial name #148

Open
ikonkere opened this issue Aug 22, 2019 · 10 comments
Open

Comments

@ikonkere
Copy link

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:

if (fileInfo.getSimpleName().equals(name)) {
.
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)) {?

@ikonkere
Copy link
Author

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.

@urbim
Copy link
Member

urbim commented Sep 2, 2019

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.

@ikonkere
Copy link
Author

ikonkere commented Sep 2, 2019

I saw you using classgraph in there, ok i'll give it a try.

@urbim urbim closed this as completed Sep 2, 2019
@ikonkere
Copy link
Author

ikonkere commented Sep 3, 2019

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.

@urbim
Copy link
Member

urbim commented Sep 5, 2019

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.

@ikonkere
Copy link
Author

ikonkere commented Sep 5, 2019

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?

@urbim
Copy link
Member

urbim commented Sep 5, 2019

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.

@ikonkere
Copy link
Author

ikonkere commented Sep 5, 2019

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.

@ikonkere
Copy link
Author

ikonkere commented Sep 6, 2019

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?

@urbim
Copy link
Member

urbim commented Sep 9, 2019

Ok, we will take a look at it.

@urbim urbim reopened this Sep 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants