Skip to content

Commit

Permalink
Merge pull request #40913 from Eng-Fouad/#35433
Browse files Browse the repository at this point in the history
Add @RegisterForProxy annotation
  • Loading branch information
gastaldi authored May 31, 2024
2 parents 73d9bae + ca40144 commit 6bc64a0
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.quarkus.deployment.steps;

import java.util.ArrayList;

import org.jboss.jandex.DotName;

import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem;
import io.quarkus.runtime.annotations.RegisterForProxy;

public class RegisterForProxyBuildStep {

@BuildStep
public void build(CombinedIndexBuildItem combinedIndexBuildItem,
BuildProducer<NativeImageProxyDefinitionBuildItem> proxy) {
for (var annotationInstance : combinedIndexBuildItem.getIndex()
.getAnnotations(DotName.createSimple(RegisterForProxy.class.getName()))) {
var targetsValue = annotationInstance.value("targets");
var types = new ArrayList<String>();
if (targetsValue == null) {
var classInfo = annotationInstance.target().asClass();
types.add(classInfo.name().toString());
classInfo.interfaceNames().forEach(dotName -> types.add(dotName.toString()));
} else {
for (var type : targetsValue.asClassArray()) {
types.add(type.name().toString());
}
}
proxy.produce(new NativeImageProxyDefinitionBuildItem(types));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.quarkus.runtime.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation that can be used to force an interface (including its super interfaces) to be registered for dynamic proxy
* generation in native image mode.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Repeatable(RegisterForProxy.List.class)
public @interface RegisterForProxy {

/**
* Alternative interfaces that should actually be registered for dynamic proxy generation instead of the current interface.
* This allows for interfaces in 3rd party libraries to be registered without modification or writing an
* extension. If this is set then the interface it is placed on is not registered for dynamic proxy generation, so this
* should generally just be placed on an empty interface that is not otherwise used.
*/
Class<?>[] targets() default {};

/**
* The repeatable holder for {@link RegisterForProxy}.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface List {
/**
* The {@link RegisterForProxy} instances.
*
* @return the instances
*/
RegisterForProxy[] value();
}
}
27 changes: 27 additions & 0 deletions docs/src/main/asciidoc/writing-native-applications-tips.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,33 @@ The final order of business is to make the configuration file known to the `nati
To do that, place the configuration file under the `src/main/resources/META-INF/native-image/<group-id>/<artifact-id>` folder.
This way they will be automatically parsed by the native build, without additional configuration.

=== Registering for proxy

Analogous to `@RegisterForReflection`, you can use `@RegisterForProxy` to register interfaces for dynamic proxy:

[source,java]
----
@RegisterForProxy
public interface MyInterface extends MySecondInterface {
}
----

Note that `MyInterface` and all its super interfaces will be registered.

Also, in case the interface is in a third-party jar, you can do it by using an empty class that will host the `@RegisterForProxy` for it.

[source,java]
----
@RegisterForProxy(targets={MyInterface.class, MySecondInterface.class})
public class MyReflectionConfiguration {
}
----

[WARNING]
====
Note that the order of the specified proxy interfaces is significant. For more information, see link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/Proxy.html[Proxy javadoc].
====

[[delay-class-init-in-your-app]]
=== Delaying class initialization

Expand Down

0 comments on commit 6bc64a0

Please sign in to comment.