How to dynamically load a Java class without using a class loader?
Asked Answered
B

7

5

I recently saw an online presentation of JRebel in which they explain what their product does, in one of the slides they mention they don't use class loaders (see screenshot below).

I have some projects in which I use class loaders for dynamically loading classes at runtime, for example for dependency injection (like in the Maker Factory framework that I developed). I thought the only way to load a class in Java was by using a class loader.

enter image description here

Bogy answered 23/7, 2014 at 20:0 Comment(2)
double check the quote, they might have written their own implementation and kinda glossed over that.. "we don't use the jre class loader"Arriviste
Actually where I read that was in a pdf that one their employees (trying to convince me to use/buy the product) sent to me, but it can also be found in: slideshare.net/boothdavid/… in slide number 8, I will also try to add a screenshot of the pdf I haveBogy
S
3

Disclaimer: I'm involved with JRebel development

Technically, it is possible to bypass the classloader with some Unsafe magic, and JVM leverages that with lambdas when creating the runtime anonymous classes (in Java 8).

However, JRebel actually integrates with the existing classloaders and doesn't create new ones - that's what the slide mean. JRebel doesn't drop the existing classloader when it has to reload a class. Instead, it loads and versions the classes within the existing classloaders.

Scamper answered 24/7, 2014 at 20:25 Comment(3)
so it does use a classloader?Arriviste
It uses the existing classloaders, of course. Otherwise, how would a Java application even execute :)Scamper
ha right, so the answer to "How to dynamically load a Java class without using a class loader?" is "You can't, but you can ...". Which is cool, just wanted to clarifyArriviste
F
6

They don't use any new classloaders; they extend the default ones.

https://www.jrebel.com/learn/how-does-jrebel-work

Fireweed answered 23/7, 2014 at 20:9 Comment(1)
@ZhekaKozlov спасибo.Fireweed
L
3

they mention they don't use class loaders.

Every class uses a ClassLoader (except primitives). However, a library doesn't have to create additional ClassLoader.

Even a "Hello World" program will have two class loaders (one for boostrapping)

I thought the only way to load a class in Java was by using a class loader.

It is, but you can force the existing classloader to load your class which is hack but might be simpler to use.

(Correction) If you use null as a ClassLoader, Unsafe.defineClass() will default to the ClassLoader of the caller.

Larissa answered 23/7, 2014 at 20:5 Comment(0)
B
3

So the answer to this question may be: There is no way to dynamically load a Java class without using a class loader for the first time. But it is possible to reload a class partially by instrumenting the class loader.

Based on Dave Newton's answer link, extracting the important things from the JRebel faq:

They use the Instrumentation API to instrument the Container/Server class loaders, that way they can dynamically monitor and control the loading process. They will scan the class-path in search of the .class file that corresponds to the loaded class and use the file timestamp to detect changes on it. When a change is detected they will propagate that change through the instrumented class loader. It will preserve the existing instances of the class but won't re-run the constructor, which means that new added fields won't be initialized.

Bogy answered 23/7, 2014 at 20:47 Comment(0)
S
3

Disclaimer: I'm involved with JRebel development

Technically, it is possible to bypass the classloader with some Unsafe magic, and JVM leverages that with lambdas when creating the runtime anonymous classes (in Java 8).

However, JRebel actually integrates with the existing classloaders and doesn't create new ones - that's what the slide mean. JRebel doesn't drop the existing classloader when it has to reload a class. Instead, it loads and versions the classes within the existing classloaders.

Scamper answered 24/7, 2014 at 20:25 Comment(3)
so it does use a classloader?Arriviste
It uses the existing classloaders, of course. Otherwise, how would a Java application even execute :)Scamper
ha right, so the answer to "How to dynamically load a Java class without using a class loader?" is "You can't, but you can ...". Which is cool, just wanted to clarifyArriviste
H
1

Indeed, the only way to load a class is through a class loader.

The JRebel folks probably meant to say that the don't use class loaders to redefine classes. Redefining a class is possible through other means, for instance through JVMTI.

Hudspeth answered 23/7, 2014 at 20:6 Comment(0)
A
0

You can of course read the class file into memory yourself. But to make the class available in your code, you still need to use ClassLoader#defineClass.

In general, any class that is used in a program must have been defined by a class loader, otherwise what should getClass().getClassLoader() return?

Abuzz answered 23/7, 2014 at 20:6 Comment(0)
T
0

For completeness, I would like to mention a new method Lookup.defineClass() which was introduced in Java 9. It allows dynamically defining new classes without all that class loader pain. The usage of the method is very easy: you just pass a byte array and you immediately get a Class<?> object. It has a limitation though: the class must be in the same package as the caller class.

Tavern answered 18/6, 2020 at 15:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.