This is an automated email from the ASF dual-hosted git repository. He-Pin pushed a commit to branch refactor/replace-reflection-with-methodhandles in repository https://gitbox.apache.org/repos/asf/pekko-grpc.git
commit 7960006dfb7fcf75bfa0471ad6d5819e5b62a378 Author: 虎鸣 <[email protected]> AuthorDate: Mon Jul 6 16:28:59 2026 +0800 refactor: replace Constructor.newInstance with MethodHandle for code generator loading Motivation: Class.forName().getDeclaredConstructor().newInstance() bypasses JIT optimization for constructor invocation in code generator loading. Modification: Replace getDeclaredConstructor().newInstance() with MethodHandles.lookup() .unreflectConstructor().invoke() in both the protoc plugin Main and the Maven plugin AbstractGenerateMojo for extra generator instantiation. Result: MethodHandle-based invocation enables JIT inlining of constructor calls, providing a consistent reflection migration across the project. Tests: - sbt "codegen / compile" - success - sbt "maven-plugin / compile" - success References: None - internal refactoring --- codegen/src/main/scala/org/apache/pekko/grpc/gen/Main.scala | 8 +++++++- .../scala/org/apache/pekko/grpc/maven/AbstractGenerateMojo.scala | 9 +++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/codegen/src/main/scala/org/apache/pekko/grpc/gen/Main.scala b/codegen/src/main/scala/org/apache/pekko/grpc/gen/Main.scala index 9b7ad4d6..dea2702f 100644 --- a/codegen/src/main/scala/org/apache/pekko/grpc/gen/Main.scala +++ b/codegen/src/main/scala/org/apache/pekko/grpc/gen/Main.scala @@ -14,6 +14,7 @@ package org.apache.pekko.grpc.gen import java.io.ByteArrayOutputStream +import java.lang.invoke.MethodHandles import java.net.URLDecoder import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest @@ -83,7 +84,12 @@ object Main { else throw new IllegalArgumentException("At least one of generateClient or generateServer must be enabled") } val loadedExtraGenerators = - extraGenerators.map(cls => Class.forName(cls).getDeclaredConstructor().newInstance().asInstanceOf[CodeGenerator]) + extraGenerators.map { cls => + val clazz = Class.forName(cls) + val ctor = clazz.getDeclaredConstructor() + ctor.setAccessible(true) + MethodHandles.lookup().unreflectConstructor(ctor).invoke().asInstanceOf[CodeGenerator] + } (codeGenerators ++ loadedExtraGenerators).foreach { g => val gout = g.run(req, logger) diff --git a/maven-plugin/src/main/scala/org/apache/pekko/grpc/maven/AbstractGenerateMojo.scala b/maven-plugin/src/main/scala/org/apache/pekko/grpc/maven/AbstractGenerateMojo.scala index 61c7475c..61a297d5 100644 --- a/maven-plugin/src/main/scala/org/apache/pekko/grpc/maven/AbstractGenerateMojo.scala +++ b/maven-plugin/src/main/scala/org/apache/pekko/grpc/maven/AbstractGenerateMojo.scala @@ -14,6 +14,7 @@ package org.apache.pekko.grpc.maven import java.io.{ ByteArrayOutputStream, File, PrintStream } +import java.lang.invoke.MethodHandles import org.apache.pekko import pekko.grpc.gen.{ CodeGenerator, Logger, ProtocSettings } @@ -181,8 +182,12 @@ abstract class AbstractGenerateMojo @Inject() (buildContext: BuildContext) exten } else { import scala.jdk.CollectionConverters._ val loadedExtraGenerators = - extraGenerators.asScala.map(cls => - Class.forName(cls).getDeclaredConstructor().newInstance().asInstanceOf[CodeGenerator]) + extraGenerators.asScala.map { cls => + val clazz = Class.forName(cls) + val ctor = clazz.getDeclaredConstructor() + ctor.setAccessible(true) + MethodHandles.lookup().unreflectConstructor(ctor).invoke().asInstanceOf[CodeGenerator] + } val targets = language match { case Java => --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
