Skip to content

Bugfix/remove classpath#4372

Closed
pollend wants to merge 2 commits into
MovingBlocks:developfrom
pollend:bugfix/remove-classpath
Closed

Bugfix/remove classpath#4372
pollend wants to merge 2 commits into
MovingBlocks:developfrom
pollend:bugfix/remove-classpath

Conversation

@pollend
Copy link
Copy Markdown
Member

@pollend pollend commented Jan 3, 2021

this reverts the changes in: 8befab3

@keturn
Copy link
Copy Markdown
Member

keturn commented Jan 3, 2021

Here's my current take on this:

This is not a build configuration error.

Some things shifted around and now single-player games (in certain dev environments) are running in to the performance problem we identified in multiplayer games in #4154 back in September.

For next steps, I suggest:

In the meantime, the stopgap workaround is:

  • don't have a ton of modules subprojects checked out in your workspace. The performance problem climbs sharply with the number of module directories.

@pollend
Copy link
Copy Markdown
Member Author

pollend commented Jan 3, 2021

I'm just using the branch to see what is different with the configuration. I don't think its a query problems. something is strange where the classloaders take a really long time to load the classes.

@keturn
Copy link
Copy Markdown
Member

keturn commented Jan 3, 2021

yeah, the note I had on that issue that I don't think is subtype-specific is

the other thing in ModuleClassLoader.loadClass I'm suspicious of is that I think a class loader should check to see if the class is already loaded before calling up the chain, as described for https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassLoader.html#loadClass(java.lang.String,boolean)

but I'm not sure ModuleClassLoader checks that first.

I don't yet understand the ModuleClassLoader thing of each classloader having a parent but ModuleClassLoaders also have a baseClassLoader, so I'm really not sure what order things happen in.

@pollend
Copy link
Copy Markdown
Member Author

pollend commented Jan 3, 2021

yeah, the note I had on that issue that I don't think is subtype-specific is

the other thing in ModuleClassLoader.loadClass I'm suspicious of is that I think a class loader should check to see if the class is already loaded before calling up the chain, as described for https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassLoader.html#loadClass(java.lang.String,boolean)
but I'm not sure ModuleClassLoader checks that first.
I don't yet understand the ModuleClassLoader thing of each classloader having a parent but ModuleClassLoaders also have a baseClassLoader, so I'm really not sure what order things happen in.

AccessController.doPrivileged(new ObtainClassloader(clazz)); seems to be the main bottleneck in the chain. that also calls ModuleSecurityManager in gestalt.

image

@pollend
Copy link
Copy Markdown
Member Author

pollend commented Jan 4, 2021

with this branch the classloader isn't chained to another module class loader. What I'm finding is that the ModuleClassloaders are getting chained to each other. Also doesn't help that reflectionutil will test the string class name with all the module loaded classloaders. This is specific to when an objects is de-serialized and we would like to look up the class by a string for its namespace and classname. I don't think we should be doing this for one the "ModuleName:TargetClass" ModuleName should resolve to the classloader for the target module and the TargetClass is what should be used to resolve the actual module.

ModuleClassLoader --> ModuleClassLoader --> ModuleClassLaoder --> BaseClassloader

below is the relevant callstack to look at.

...
org.terasology.persistence.typeHandling.coreTypes.RuntimeDelegatingTypeHandler.findSubtypeWithName(String)
org.terasology.persistence.typeHandling.reflection.ModuleEnvironmentSandbox.findSubTypeOf(String, Class)
org.terasology.reflection.TypeRegistry.load(String)
org.reflections.ReflectionUtils.forName(String, ClassLoader[])
java.lang.ClassLoader.loadClass(String)
org.terasology.module.sandbox.ModuleClassLoader.loadClass(String, boolean)
java.lang.ClassLoader.loadClass(String, boolean)
...

@keturn keturn marked this pull request as draft January 4, 2021 02:41
@Cervator Cervator added Topic: Architecture Requests, Issues and Changes related to software architecture, programming patterns, etc. Category: Build/CI Requests, Issues and Changes targeting gradle, groovy, Jenkins, etc. labels Jan 4, 2021
@keturn
Copy link
Copy Markdown
Member

keturn commented Jan 4, 2021

on the security (not performance) impacts of the classpath thing: #4375

@keturn
Copy link
Copy Markdown
Member

keturn commented Jan 9, 2021

why does this show up when running from IntelliJ but not gradle? Likely clue:

gradle is putting the jar files on the classpath, but IntelliJ is giving the classes directory.

It's not wrong to use the directories here. It might help module and asset hot-reloading speed in development and saves a build step. gradle might well do the same thing if the configuration changes a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Category: Build/CI Requests, Issues and Changes targeting gradle, groovy, Jenkins, etc. Topic: Architecture Requests, Issues and Changes related to software architecture, programming patterns, etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants