You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pekko.apache.org by he...@apache.org on 2026/07/06 08:29:22 UTC
(pekko-grpc) 01/01: refactor: replace Constructor.newInstance with MethodHandle for code generator loading
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: 虎鸣 <he...@alibaba-inc.com>
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: commits-unsubscribe@pekko.apache.org
For additional commands, e-mail: commits-help@pekko.apache.org