This is an automated email from the ASF dual-hosted git repository.

earthchen pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.3 by this push:
     new d0c41f512e feat:remove jprotoc (#13145)
d0c41f512e is described below

commit d0c41f512e3478ad10ed37b5196bee38c60b578d
Author: XiaoYu <[email protected]>
AuthorDate: Thu Oct 19 12:32:38 2023 +0800

    feat:remove jprotoc (#13145)
    
    * feat:remove jprotoc
    
    * fix:add dependency and license
    
    * fix:remove useless import
    
    * fix:checkstyle bug
    
    * fix:SonarCloud bug
    
    * refactor:remove a package path
    
    * fix:handle InterruptedException
    
    * refactor:modify license and format code
    
    * fix:checkstyle excluded
    
    * Add NOTICE
    
    * fix:remove unless notice
    
    * refactor:code format
    
    ---------
    
    Co-authored-by: Albumen Kevin <[email protected]>
    Co-authored-by: pengxiaoyu <[email protected]>
---
 .licenserc.yaml                                    |   2 +
 NOTICE                                             |  20 ++
 dubbo-compiler/README.md                           | 137 ++++++++
 dubbo-compiler/pom.xml                             |   4 +-
 .../org/apache/dubbo/gen/AbstractGenerator.java    |  48 ++-
 .../org/apache/dubbo/gen/DubboGeneratorPlugin.java |  47 +++
 .../apache/dubbo/gen/dubbo/Dubbo3Generator.java    |   9 +-
 .../org/apache/dubbo/gen/dubbo/DubboGenerator.java |   8 +-
 .../apache/dubbo/gen/grpc/DubboGrpcGenerator.java  |   8 +-
 .../grpc/reactive/ReactorDubboGrpcGenerator.java   |   9 +-
 .../gen/grpc/reactive/RxDubboGrpcGenerator.java    |   9 +-
 .../dubbo/gen/tri/Dubbo3TripleGenerator.java       |   9 +-
 .../tri/reactive/ReactorDubbo3TripleGenerator.java |   8 +-
 .../org/apache/dubbo/gen/utils/ProtoTypeMap.java   | 123 +++++++
 dubbo-dependencies-bom/pom.xml                     |   6 +
 dubbo-maven-plugin/pom.xml                         |  12 +
 .../plugin/protoc/DubboProtocCompilerMojo.java     | 385 +++++++++++++++++++++
 .../maven/plugin/protoc/DubboProtocPlugin.java     | 140 ++++++++
 .../plugin/protoc/DubboProtocPluginWrapper.java    |  26 +-
 .../protoc/DubboProtocPluginWrapperFactory.java    |  46 +++
 .../protoc/LinuxDubboProtocPluginWrapper.java      |  84 +++++
 .../dubbo/maven/plugin/protoc/ProtocMetaData.java  |  85 +++++
 .../plugin/protoc/WinDubboProtocPluginWrapper.java | 153 ++++++++
 .../command/DefaultProtocCommandBuilder.java       |  43 +++
 .../protoc/command/ProtocCommandArgsBuilder.java   |  26 +-
 .../plugin/protoc/enums/DubboGenerateTypeEnum.java |  60 ++++
 pom.xml                                            |   2 +
 27 files changed, 1403 insertions(+), 106 deletions(-)

diff --git a/.licenserc.yaml b/.licenserc.yaml
index 2199c97a86..4a1d226ff1 100644
--- a/.licenserc.yaml
+++ b/.licenserc.yaml
@@ -104,6 +104,8 @@ header:
     - 
'dubbo-annotation-processor/src/main/java/org/apache/dubbo/annotation/permit/**'
     - 
'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/FormattingTuple.java'
     - 
'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/MessageFormatter.java'
+    - 
'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java'
+    - 
'dubbo-compiler/src/main/java/org/apache/dubbo/gen/utils/ProtoTypeMap.java'
 
   comment: on-failure
 
diff --git a/NOTICE b/NOTICE
index b862c0f833..6b0e80946f 100644
--- a/NOTICE
+++ b/NOTICE
@@ -16,3 +16,23 @@ Copyright 2014 The Netty Project
 This product contains code form the t-digest Project:
 The code for the t-digest was originally authored by Ted Dunning
 Adrien Grand contributed the heart of the AVLTreeDigest 
(https://github.com/jpountz)
+
+This product contains the following code copied from Maven Protocol Buffers 
Plugin:
+dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java
+
+Maven Protocol Buffers Plugin
+=============================
+Copyright (c) 2016 Maven Protocol Buffers Plugin Authors. All rights reserved.
+
+This product contains the following code copied from grpc-java-contrib:
+dubbo-compiler/src/main/java/org/apache/dubbo/gen/utils/ProtoTypeMap.java
+Some portions of this file Copyright (c) 2019, Salesforce.com, Inc. and 
licensed under the BSD 3-Clause License
+
+grpc-java-contrib
+====================
+Copyright (c) 2019, Salesforce.com, Inc.
+All rights reserved.
+
+
+
+
diff --git a/dubbo-compiler/README.md b/dubbo-compiler/README.md
new file mode 100644
index 0000000000..f3e13e5a1a
--- /dev/null
+++ b/dubbo-compiler/README.md
@@ -0,0 +1,137 @@
+## dubbo-complier
+
+> dubbo-complier supports generating code based on .proto files
+
+### How to use 
+
+#### 1.Define Proto file
+
+greeter.proto
+```protobuf
+syntax = "proto3";
+
+option java_multiple_files = true;
+option java_package = "org.apache.dubbo.demo";
+option java_outer_classname = "DemoServiceProto";
+option objc_class_prefix = "DEMOSRV";
+
+package demoservice;
+
+// The demo service definition.
+service DemoService {
+  rpc SayHello (HelloRequest) returns (HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+  string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+  string message = 1;
+}
+
+```
+
+#### 2.Use dubbo-maven-plugin,rather than ```protobuf-maven-plugin```
+
+    now dubbo support his own protoc plugin base on dubbo-maven-plugin
+
+```xml
+  <plugin>
+    <groupId>org.apache.dubbo</groupId>
+    <artifactId>dubbo-maven-plugin</artifactId>
+    <version>3.3.0</version>
+    <configuration>
+        <dubboVersion>3.3.0</dubboVersion>
+        <dubboGenerateType>dubbo3</dubboGenerateType>
+        <protocExecutable>protoc</protocExecutable>
+        
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
+    </configuration>
+</plugin>
+
+```
+
+#### 3.generate file
+
+```java
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+    package org.apache.dubbo.demo;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public final class DemoServiceDubbo {
+private static final AtomicBoolean registered = new AtomicBoolean();
+
+private static Class<?> init() {
+Class<?> clazz = null;
+try {
+clazz = Class.forName(DemoServiceDubbo.class.getName());
+if (registered.compareAndSet(false, true)) {
+    
org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller(
+    org.apache.dubbo.demo.HelloReply.getDefaultInstance());
+    
org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller(
+    org.apache.dubbo.demo.HelloRequest.getDefaultInstance());
+}
+} catch (ClassNotFoundException e) {
+// ignore
+}
+return clazz;
+}
+
+private DemoServiceDubbo() {}
+
+public static final String SERVICE_NAME = "org.apache.dubbo.demo.DemoService";
+
+/**
+* Code generated for Dubbo
+*/
+public interface IDemoService extends org.apache.dubbo.rpc.model.DubboStub {
+
+static Class<?> clazz = init();
+
+    org.apache.dubbo.demo.HelloReply 
sayHello(org.apache.dubbo.demo.HelloRequest request);
+
+    CompletableFuture<org.apache.dubbo.demo.HelloReply> 
sayHelloAsync(org.apache.dubbo.demo.HelloRequest request);
+
+
+}
+
+}
+
+```
+
+#### 4.others
+
+dubbo-maven-plugin protoc mojo supported configurations
+
+| configuration params  | isRequired | explain                                 
       | default                                                    | eg        
                                                                 |
+|:----------------------|------------|------------------------------------------------|------------------------------------------------------------|----------------------------------------------------------------------------|
+| dubboVersion          | true       | dubbo version ,use for find Generator   
       | ${dubbo.version}                                           | 3.3.0     
                                                                 |
+| dubboGenerateType     | true       | dubbo generator type                    
       | dubbo3                                                     | grpc      
                                                                 |
+| protocExecutable      | false      | protoc executable,you can use local 
protoc.exe |                                                            | 
protoc                                                                     |
+| protocArtifact        | false      | download protoc from maven artifact     
       |                                                            | 
com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} |
+| protoSourceDir        | true       | .proto files dir                        
       | ${basedir}/src/main/proto                                  | ./proto   
                                                                 |
+| outputDir             | true       | generated file output dir               
       | ${project.build.directory}/generated-sources/protobuf/java | 
${basedir}/src/main/java                                                   |
+| protocPluginDirectory | false      | protoc plugin dir                       
       | ${project.build.directory}/protoc-plugins                  | 
./target/protoc-plugins                                                    |
+
+
+​    
diff --git a/dubbo-compiler/pom.xml b/dubbo-compiler/pom.xml
index 5cb8a9c8a7..2d445e4a1e 100644
--- a/dubbo-compiler/pom.xml
+++ b/dubbo-compiler/pom.xml
@@ -37,8 +37,8 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.salesforce.servicelibs</groupId>
-            <artifactId>jprotoc</artifactId>
+            <groupId>com.github.spullara.mustache.java</groupId>
+            <artifactId>compiler</artifactId>
         </dependency>
         <dependency>
             <groupId>io.grpc</groupId>
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java
index de9e67bd8c..e2d387eae4 100644
--- a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java
+++ b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java
@@ -16,6 +16,11 @@
  */
 package org.apache.dubbo.gen;
 
+import com.github.mustachejava.DefaultMustacheFactory;
+import com.github.mustachejava.Mustache;
+import com.github.mustachejava.MustacheFactory;
+import com.google.common.base.Charsets;
+import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import com.google.common.html.HtmlEscapers;
 import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
@@ -23,22 +28,23 @@ import com.google.protobuf.DescriptorProtos.FileOptions;
 import com.google.protobuf.DescriptorProtos.MethodDescriptorProto;
 import com.google.protobuf.DescriptorProtos.ServiceDescriptorProto;
 import com.google.protobuf.DescriptorProtos.SourceCodeInfo.Location;
-import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.Feature;
 import com.google.protobuf.compiler.PluginProtos;
-import com.salesforce.jprotoc.Generator;
-import com.salesforce.jprotoc.GeneratorException;
-import com.salesforce.jprotoc.ProtoTypeMap;
+import org.apache.dubbo.gen.utils.ProtoTypeMap;
 
+import javax.annotation.Nonnull;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
-public abstract class AbstractGenerator extends Generator {
+public abstract class AbstractGenerator  {
 
+    private static final MustacheFactory MUSTACHE_FACTORY = new 
DefaultMustacheFactory();
     private static final int SERVICE_NUMBER_OF_PATHS = 2;
     private static final int METHOD_NUMBER_OF_PATHS = 4;
 
@@ -58,10 +64,6 @@ public abstract class AbstractGenerator extends Generator {
         return getClassPrefix() + getClassSuffix() + "InterfaceStub.mustache";
     }
 
-    @Override
-    protected List<Feature> supportedFeatures() {
-        return Collections.singletonList(Feature.FEATURE_PROTO3_OPTIONAL);
-    }
 
     private String getServiceJavaDocPrefix() {
         return "    ";
@@ -71,9 +73,7 @@ public abstract class AbstractGenerator extends Generator {
         return "        ";
     }
 
-    @Override
-    public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(
-        PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
+    public List<PluginProtos.CodeGeneratorResponse.File> 
generateFiles(PluginProtos.CodeGeneratorRequest request) {
         final ProtoTypeMap typeMap = 
ProtoTypeMap.of(request.getProtoFileList());
 
         List<FileDescriptorProto> protosToGenerate = 
request.getProtoFileList().stream()
@@ -85,12 +85,12 @@ public abstract class AbstractGenerator extends Generator {
     }
 
     private List<ServiceContext> findServices(List<FileDescriptorProto> protos,
-        ProtoTypeMap typeMap) {
+                                              ProtoTypeMap typeMap) {
         List<ServiceContext> contexts = new ArrayList<>();
 
         protos.forEach(fileProto -> {
             for (int serviceNumber = 0; serviceNumber < 
fileProto.getServiceCount();
-                serviceNumber++) {
+                 serviceNumber++) {
                 ServiceContext serviceContext = buildServiceContext(
                     fileProto.getService(serviceNumber),
                     typeMap,
@@ -127,7 +127,7 @@ public abstract class AbstractGenerator extends Generator {
     }
 
     private ServiceContext buildServiceContext(ServiceDescriptorProto 
serviceProto,
-        ProtoTypeMap typeMap, List<Location> locations, int serviceNumber) {
+                                               ProtoTypeMap typeMap, 
List<Location> locations, int serviceNumber) {
         ServiceContext serviceContext = new ServiceContext();
         serviceContext.fileName =
             getClassPrefix() + serviceProto.getName() + getClassSuffix() + 
".java";
@@ -170,7 +170,7 @@ public abstract class AbstractGenerator extends Generator {
     }
 
     private MethodContext buildMethodContext(MethodDescriptorProto methodProto,
-        ProtoTypeMap typeMap, List<Location> locations, int methodNumber) {
+                                             ProtoTypeMap typeMap, 
List<Location> locations, int methodNumber) {
         MethodContext methodContext = new MethodContext();
         methodContext.originMethodName = methodProto.getName();
         methodContext.methodName = lowerCaseFirst(methodProto.getName());
@@ -261,6 +261,20 @@ public abstract class AbstractGenerator extends Generator {
         return files;
     }
 
+    protected String applyTemplate(@Nonnull String resourcePath, @Nonnull 
Object generatorContext) {
+        Preconditions.checkNotNull(resourcePath, "resourcePath");
+        Preconditions.checkNotNull(generatorContext, "generatorContext");
+        InputStream resource = 
MustacheFactory.class.getClassLoader().getResourceAsStream(resourcePath);
+        if (resource == null) {
+            throw new RuntimeException("Could not find resource " + 
resourcePath);
+        } else {
+            InputStreamReader resourceReader = new InputStreamReader(resource, 
Charsets.UTF_8);
+            Mustache template = MUSTACHE_FACTORY.compile(resourceReader, 
resourcePath);
+            return template.execute(new StringWriter(), 
generatorContext).toString();
+        }
+    }
+
+
     private String absoluteDir(ServiceContext ctx) {
         return ctx.packageName.replace('.', '/');
     }
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/DubboGeneratorPlugin.java 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/DubboGeneratorPlugin.java
new file mode 100644
index 0000000000..70254505dc
--- /dev/null
+++ 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/DubboGeneratorPlugin.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.gen;
+
+import com.google.protobuf.compiler.PluginProtos;
+
+import java.io.IOException;
+import java.util.List;
+
+
+public class DubboGeneratorPlugin {
+
+    public static void generate(AbstractGenerator generator) {
+        try{
+            PluginProtos.CodeGeneratorRequest request = 
PluginProtos.CodeGeneratorRequest.parseFrom(System.in);
+            List<PluginProtos.CodeGeneratorResponse.File> files = 
generator.generateFiles(request);
+            
PluginProtos.CodeGeneratorResponse.newBuilder().addAllFile(files).setSupportedFeatures(PluginProtos.CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL.getNumber()).build().writeTo(System.out);
+        }catch (Exception e){
+            try {
+                
PluginProtos.CodeGeneratorResponse.newBuilder().setError(e.getMessage()).build().writeTo(System.out);
+            } catch (IOException var6) {
+                exit(e);
+            }
+        }catch (Throwable var8) {
+            exit(var8);
+        }
+    }
+
+    public static void exit(Throwable e){
+        e.printStackTrace(System.err);
+        System.exit(1);
+    }
+}
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/Dubbo3Generator.java 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/Dubbo3Generator.java
index 29a789b22e..f10bec29e8 100644
--- 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/Dubbo3Generator.java
+++ 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/Dubbo3Generator.java
@@ -17,17 +17,12 @@
 package org.apache.dubbo.gen.dubbo;
 
 import org.apache.dubbo.gen.AbstractGenerator;
-
-import com.salesforce.jprotoc.ProtocPlugin;
+import org.apache.dubbo.gen.DubboGeneratorPlugin;
 
 public class Dubbo3Generator extends AbstractGenerator {
 
     public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new Dubbo3Generator());
-        } else {
-            ProtocPlugin.debug(new Dubbo3Generator(), args[0]);
-        }
+        DubboGeneratorPlugin.generate(new Dubbo3Generator());
     }
 
     @Override
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
index 1abf2a0064..8b20009a2a 100644
--- 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
+++ 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
@@ -17,17 +17,13 @@
 package org.apache.dubbo.gen.dubbo;
 
 import org.apache.dubbo.gen.AbstractGenerator;
+import org.apache.dubbo.gen.DubboGeneratorPlugin;
 
-import com.salesforce.jprotoc.ProtocPlugin;
 
 public class DubboGenerator extends AbstractGenerator {
 
     public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new DubboGenerator());
-        } else {
-            ProtocPlugin.debug(new DubboGenerator(), args[0]);
-        }
+        DubboGeneratorPlugin.generate(new DubboGenerator());
     }
 
     @Override
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java
 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java
index dafdd5a6e6..e8608545c5 100644
--- 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java
+++ 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java
@@ -17,17 +17,13 @@
 package org.apache.dubbo.gen.grpc;
 
 import org.apache.dubbo.gen.AbstractGenerator;
+import org.apache.dubbo.gen.DubboGeneratorPlugin;
 
-import com.salesforce.jprotoc.ProtocPlugin;
 
 public class DubboGrpcGenerator extends AbstractGenerator {
 
     public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new DubboGrpcGenerator());
-        } else {
-            ProtocPlugin.debug(new DubboGrpcGenerator(), args[0]);
-        }
+        DubboGeneratorPlugin.generate(new DubboGrpcGenerator());
     }
 
     @Override
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java
 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java
index dd9520b902..ef80564ccd 100644
--- 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java
+++ 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java
@@ -17,8 +17,9 @@
 package org.apache.dubbo.gen.grpc.reactive;
 
 import org.apache.dubbo.gen.AbstractGenerator;
+import org.apache.dubbo.gen.DubboGeneratorPlugin;
+
 
-import com.salesforce.jprotoc.ProtocPlugin;
 
 public class ReactorDubboGrpcGenerator extends AbstractGenerator {
 
@@ -33,10 +34,6 @@ public class ReactorDubboGrpcGenerator extends 
AbstractGenerator {
     }
 
     public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new ReactorDubboGrpcGenerator());
-        } else {
-            ProtocPlugin.debug(new ReactorDubboGrpcGenerator(), args[0]);
-        }
+        DubboGeneratorPlugin.generate(new ReactorDubboGrpcGenerator());
     }
 }
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java
 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java
index 028332a27e..e81e90f57d 100644
--- 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java
+++ 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java
@@ -17,8 +17,7 @@
 package org.apache.dubbo.gen.grpc.reactive;
 
 import org.apache.dubbo.gen.AbstractGenerator;
-
-import com.salesforce.jprotoc.ProtocPlugin;
+import org.apache.dubbo.gen.DubboGeneratorPlugin;
 
 public class RxDubboGrpcGenerator extends AbstractGenerator {
     @Override
@@ -32,10 +31,6 @@ public class RxDubboGrpcGenerator extends AbstractGenerator {
     }
 
     public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new RxDubboGrpcGenerator());
-        } else {
-            ProtocPlugin.debug(new RxDubboGrpcGenerator(), args[0]);
-        }
+        DubboGeneratorPlugin.generate(new RxDubboGrpcGenerator());
     }
 }
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/tri/Dubbo3TripleGenerator.java
 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/tri/Dubbo3TripleGenerator.java
index ae3f8c0539..9b08e2a502 100644
--- 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/tri/Dubbo3TripleGenerator.java
+++ 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/tri/Dubbo3TripleGenerator.java
@@ -17,17 +17,12 @@
 package org.apache.dubbo.gen.tri;
 
 import org.apache.dubbo.gen.AbstractGenerator;
-
-import com.salesforce.jprotoc.ProtocPlugin;
+import org.apache.dubbo.gen.DubboGeneratorPlugin;
 
 public class Dubbo3TripleGenerator extends AbstractGenerator {
 
     public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new Dubbo3TripleGenerator());
-        } else {
-            ProtocPlugin.debug(new Dubbo3TripleGenerator(), args[0]);
-        }
+        DubboGeneratorPlugin.generate(new Dubbo3TripleGenerator());
     }
 
     @Override
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/tri/reactive/ReactorDubbo3TripleGenerator.java
 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/tri/reactive/ReactorDubbo3TripleGenerator.java
index dfc8d86e61..a5d2f55abc 100644
--- 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/tri/reactive/ReactorDubbo3TripleGenerator.java
+++ 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/tri/reactive/ReactorDubbo3TripleGenerator.java
@@ -17,17 +17,13 @@
 
 package org.apache.dubbo.gen.tri.reactive;
 
-import com.salesforce.jprotoc.ProtocPlugin;
 import org.apache.dubbo.gen.AbstractGenerator;
+import org.apache.dubbo.gen.DubboGeneratorPlugin;
 
 public class ReactorDubbo3TripleGenerator extends AbstractGenerator {
 
     public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new ReactorDubbo3TripleGenerator());
-        } else {
-            ProtocPlugin.debug(new ReactorDubbo3TripleGenerator(), args[0]);
-        }
+        DubboGeneratorPlugin.generate(new ReactorDubbo3TripleGenerator());
     }
 
     @Override
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/utils/ProtoTypeMap.java 
b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/utils/ProtoTypeMap.java
new file mode 100644
index 0000000000..e725cf88a0
--- /dev/null
+++ b/dubbo-compiler/src/main/java/org/apache/dubbo/gen/utils/ProtoTypeMap.java
@@ -0,0 +1,123 @@
+/*
+ *  Copyright (c) 2019, Salesforce.com, Inc.
+ *  All rights reserved.
+ *  Licensed under the BSD 3-Clause license.
+ *  For full license text, see LICENSE.txt file in the repo root  or 
https://opensource.org/licenses/BSD-3-Clause
+ */
+package org.apache.dubbo.gen.utils;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.protobuf.DescriptorProtos;
+
+import javax.annotation.Nonnull;
+import java.util.Collection;
+
+public final class ProtoTypeMap {
+    private static final Joiner DOT_JOINER = Joiner.on('.').skipNulls();
+    private final ImmutableMap<String, String> types;
+
+    private ProtoTypeMap(@Nonnull ImmutableMap<String, String> types) {
+        Preconditions.checkNotNull(types, "types");
+        this.types = types;
+    }
+
+    public static ProtoTypeMap of(@Nonnull 
Collection<DescriptorProtos.FileDescriptorProto> fileDescriptorProtos) {
+        Preconditions.checkNotNull(fileDescriptorProtos, 
"fileDescriptorProtos");
+        Preconditions.checkArgument(!fileDescriptorProtos.isEmpty(), 
"fileDescriptorProtos.isEmpty()");
+        ImmutableMap.Builder<String, String> types = ImmutableMap.builder();
+
+        for (DescriptorProtos.FileDescriptorProto fileDescriptor : 
fileDescriptorProtos) {
+            DescriptorProtos.FileOptions fileOptions = 
fileDescriptor.getOptions();
+            String protoPackage = fileDescriptor.hasPackage() ? "." + 
fileDescriptor.getPackage() : "";
+            String javaPackage = 
Strings.emptyToNull(fileOptions.hasJavaPackage() ? fileOptions.getJavaPackage() 
: fileDescriptor.getPackage());
+            String enclosingClassName = fileOptions.getJavaMultipleFiles() ? 
null : getJavaOuterClassname(fileDescriptor, fileOptions);
+            fileDescriptor.getEnumTypeList().forEach((e) -> {
+                types.put(protoPackage + "." + e.getName(), 
DOT_JOINER.join(javaPackage, enclosingClassName, new Object[]{e.getName()}));
+            });
+            fileDescriptor.getMessageTypeList().forEach((m) -> {
+                recursivelyAddTypes(types, m, protoPackage, 
enclosingClassName, javaPackage);
+            });
+        }
+
+        return new ProtoTypeMap(types.build());
+    }
+
+    private static void recursivelyAddTypes(ImmutableMap.Builder<String, 
String> types, DescriptorProtos.DescriptorProto m, String protoPackage, String 
enclosingClassName, String javaPackage) {
+        String protoTypeName = protoPackage + "." + m.getName();
+        types.put(protoTypeName, DOT_JOINER.join(javaPackage, 
enclosingClassName, new Object[]{m.getName()}));
+        m.getEnumTypeList().forEach((e) -> {
+            types.put(protoPackage + "." + m.getName() + "." + e.getName(), 
DOT_JOINER.join(javaPackage, enclosingClassName, new Object[]{m.getName(), 
e.getName()}));
+        });
+        m.getNestedTypeList().forEach((n) -> {
+            recursivelyAddTypes(types, n, protoPackage + "." + m.getName(), 
DOT_JOINER.join(enclosingClassName, m.getName(), new Object[0]), javaPackage);
+        });
+    }
+
+    public String toJavaTypeName(@Nonnull String protoTypeName) {
+        Preconditions.checkNotNull(protoTypeName, "protoTypeName");
+        return (String)this.types.get(protoTypeName);
+    }
+
+    private static String 
getJavaOuterClassname(DescriptorProtos.FileDescriptorProto fileDescriptor, 
DescriptorProtos.FileOptions fileOptions) {
+        if (fileOptions.hasJavaOuterClassname()) {
+            return fileOptions.getJavaOuterClassname();
+        } else {
+            String filename = fileDescriptor.getName().substring(0, 
fileDescriptor.getName().length() - ".proto".length());
+            if (filename.contains("/")) {
+                filename = filename.substring(filename.lastIndexOf(47) + 1);
+            }
+
+            filename = makeInvalidCharactersUnderscores(filename);
+            filename = convertToCamelCase(filename);
+            filename = appendOuterClassSuffix(filename, fileDescriptor);
+            return filename;
+        }
+    }
+
+    private static String appendOuterClassSuffix(String enclosingClassName, 
DescriptorProtos.FileDescriptorProto fd) {
+        return !fd.getEnumTypeList().stream().anyMatch((enumProto) -> {
+            return enumProto.getName().equals(enclosingClassName);
+        }) && !fd.getMessageTypeList().stream().anyMatch((messageProto) -> {
+            return messageProto.getName().equals(enclosingClassName);
+        }) && !fd.getServiceList().stream().anyMatch((serviceProto) -> {
+            return serviceProto.getName().equals(enclosingClassName);
+        }) ? enclosingClassName : enclosingClassName + "OuterClass";
+    }
+
+    private static String makeInvalidCharactersUnderscores(String filename) {
+        char[] filechars = filename.toCharArray();
+
+        for(int i = 0; i < filechars.length; ++i) {
+            char c = filechars[i];
+            if (!CharMatcher.inRange('0', '9').or(CharMatcher.inRange('A', 
'Z')).or(CharMatcher.inRange('a', 'z')).matches(c)) {
+                filechars[i] = '_';
+            }
+        }
+
+        return new String(filechars);
+    }
+
+    private static String convertToCamelCase(String name) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(Character.toUpperCase(name.charAt(0)));
+
+        for(int i = 1; i < name.length(); ++i) {
+            char c = name.charAt(i);
+            char prev = name.charAt(i - 1);
+            if (c != '_') {
+                if (prev != '_' && !CharMatcher.inRange('0', 
'9').matches(prev)) {
+                    sb.append(c);
+                } else {
+                    sb.append(Character.toUpperCase(c));
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+}
+
diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml
index 89719f7cb6..07fca6d4d3 100644
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@ -155,6 +155,7 @@
         <grpc.version>1.58.0</grpc.version>
         <grpc_contrib_verdion>0.8.1</grpc_contrib_verdion>
         <jprotoc_version>1.2.2</jprotoc_version>
+        <mustache_version>0.9.10</mustache_version>
         <!-- Log libs -->
         <slf4j_version>1.7.36</slf4j_version>
         <jcl_version>1.2</jcl_version>
@@ -889,6 +890,11 @@
                 <artifactId>jprotoc</artifactId>
                 <version>${jprotoc_version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.github.spullara.mustache.java</groupId>
+                <artifactId>compiler</artifactId>
+                <version>${mustache_version}</version>
+            </dependency>
             <dependency>
                 <groupId>io.fabric8</groupId>
                 <artifactId>kubernetes-client</artifactId>
diff --git a/dubbo-maven-plugin/pom.xml b/dubbo-maven-plugin/pom.xml
index 0b3302d763..bff3ce7aa6 100644
--- a/dubbo-maven-plugin/pom.xml
+++ b/dubbo-maven-plugin/pom.xml
@@ -70,6 +70,18 @@
             <artifactId>commons-io</artifactId>
             <version>2.11.0</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.sonatype.plexus</groupId>
+            <artifactId>plexus-build-api</artifactId>
+            <version>0.0.7</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.codehaus.plexus</groupId>
+                    <artifactId>plexus-utils</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java
 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java
new file mode 100644
index 0000000000..e2c88b6c7e
--- /dev/null
+++ 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2019 Maven Protocol Buffers Plugin Authors. All rights 
reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.maven.plugin.protoc;
+
+import 
org.apache.dubbo.maven.plugin.protoc.command.DefaultProtocCommandBuilder;
+import org.apache.dubbo.maven.plugin.protoc.enums.DubboGenerateTypeEnum;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
+import 
org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectHelper;
+import org.apache.maven.repository.RepositorySystem;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.Os;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.cli.CommandLineException;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.Arrays;
+
+import static java.lang.String.format;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.singleton;
+import static org.codehaus.plexus.util.FileUtils.getFiles;
+
+@Mojo(name = "dubbo-protoc-compiler")
+public class DubboProtocCompilerMojo extends AbstractMojo {
+    @Parameter(property = "protoSourceDir", defaultValue = 
"${basedir}/src/main/proto")
+    private File protoSourceDir;
+    @Parameter(property = "outputDir", defaultValue = 
"${project.build.directory}/generated-sources/protobuf/java")
+    private File outputDir;
+    @Parameter(required = true, property = "dubboVersion", defaultValue = 
"${dubbo.version}")
+    private String dubboVersion;
+    @Parameter(required = true, readonly = true, defaultValue = 
"${project.remoteArtifactRepositories}")
+    private List<ArtifactRepository> remoteRepositories;
+    @Parameter(required = false, property = "protocExecutable")
+    private String protocExecutable;
+    @Parameter(required = false, property = "protocArtifact")
+    private String protocArtifact;
+    @Parameter(required = false, defaultValue = 
"${project.build.directory}/protoc-plugins")
+    private File protocPluginDirectory;
+    @Parameter(required = true, property = "dubboGenerateType", defaultValue = 
"dubbo3")
+    private String dubboGenerateType;
+    @Parameter(defaultValue = "${project}", readonly = true)
+    protected MavenProject project;
+    @Parameter(defaultValue = "${session}", readonly = true)
+    protected MavenSession session;
+    @Parameter(required = true, readonly = true, property = "localRepository")
+    private ArtifactRepository localRepository;
+    @Component
+    private ArtifactFactory artifactFactory;
+    @Component
+    private RepositorySystem repositorySystem;
+    @Component
+    private ResolutionErrorHandler resolutionErrorHandler;
+    @Component
+    protected MavenProjectHelper projectHelper;
+    @Component
+    protected BuildContext buildContext;
+    final CommandLineUtils.StringStreamConsumer output = new 
CommandLineUtils.StringStreamConsumer();
+    final CommandLineUtils.StringStreamConsumer error = new 
CommandLineUtils.StringStreamConsumer();
+    private final DefaultProtocCommandBuilder defaultProtocCommandBuilder = 
new DefaultProtocCommandBuilder();
+    private final DubboProtocPluginWrapperFactory 
dubboProtocPluginWrapperFactory = new DubboProtocPluginWrapperFactory();
+
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        if (protocExecutable == null && protocArtifact != null) {
+            final Artifact artifact = createProtocArtifact(protocArtifact);
+            final File file = resolveBinaryArtifact(artifact);
+            protocExecutable = file.getAbsolutePath();
+        }
+        if (protocExecutable == null) {
+            getLog().warn("No 'protocExecutable' parameter is configured, 
using the default: 'protoc'");
+            protocExecutable = "protoc";
+        }
+        getLog().info("using protocExecutable: " + protocExecutable);
+        DubboProtocPlugin dubboProtocPlugin = 
buildDubboProtocPlugin(dubboVersion, dubboGenerateType, protocPluginDirectory);
+        getLog().info("build dubbo protoc plugin:" + dubboProtocPlugin + " 
success");
+        List<String> commandArgs = 
defaultProtocCommandBuilder.buildProtocCommandArgs(new ProtocMetaData(
+            protocExecutable, protoSourceDir, 
findAllProtoFiles(protoSourceDir), outputDir, dubboProtocPlugin
+        ));
+        if (!outputDir.exists()) {
+            FileUtils.mkdir(outputDir.getAbsolutePath());
+        }
+        try {
+            int exitStatus = executeCommandLine(commandArgs);
+            getLog().info("execute commandLine finished with exit code: " + 
exitStatus);
+            if (exitStatus != 0) {
+                getLog().error("PROTOC FAILED: " + getError());
+                throw new MojoFailureException(
+                    "protoc did not exit cleanly. Review output for more 
information.");
+            } else if (StringUtils.isNotBlank(getError())) {
+                getLog().warn("PROTOC: " + getError());
+            } else {
+                linkProtoFilesToMaven();
+            }
+        } catch (CommandLineException e) {
+            throw new MojoExecutionException(e);
+        }
+    }
+
+    public void linkProtoFilesToMaven() {
+        linkProtoSources();
+        linkGeneratedFiles();
+    }
+
+    public void linkProtoSources() {
+        projectHelper.addResource(project, protoSourceDir.getAbsolutePath(),
+            Collections.singletonList("**/*.proto*"), 
Collections.singletonList(""));
+    }
+
+    public void linkGeneratedFiles() {
+        project.addCompileSourceRoot(outputDir.getAbsolutePath());
+        buildContext.refresh(outputDir);
+    }
+
+    public List<File> findAllProtoFiles(final File protoSourceDir) {
+        if (protoSourceDir == null) {
+            throw new RuntimeException("'protoSourceDir' is null");
+        }
+        if (!protoSourceDir.isDirectory()) {
+            throw new RuntimeException(format("%s is not a directory", 
protoSourceDir));
+        }
+        final List<File> protoFilesInDirectory;
+        try {
+            protoFilesInDirectory = getFiles(protoSourceDir, "**/*.proto*", 
"");
+        } catch (IOException e) {
+            throw new RuntimeException("Unable to retrieve the list of files: 
" + e.getMessage(), e);
+        }
+        getLog().info("protoFilesInDirectory: " + protoFilesInDirectory);
+        return protoFilesInDirectory;
+    }
+
+    public int executeCommandLine(List<String> commandArgs) throws 
CommandLineException {
+        final Commandline cl = new Commandline();
+        cl.setExecutable(protocExecutable);
+        cl.addArguments(commandArgs.toArray(new String[]{}));
+        int attemptsLeft = 3;
+        while (true) {
+            try {
+                getLog().info("commandLine:" + cl.toString());
+                return CommandLineUtils.executeCommandLine(cl, null, output, 
error);
+            } catch (CommandLineException e) {
+                if (--attemptsLeft == 0 || e.getCause() == null) {
+                    throw e;
+                }
+                getLog().warn("[PROTOC] Unable to invoke protoc, will retry " 
+ attemptsLeft + " time(s)", e);
+                try {
+                    Thread.sleep(1000L);
+                } catch (InterruptedException ex) {
+                    Thread.currentThread().interrupt();
+                    throw new RuntimeException(ex);
+                }
+            }
+        }
+    }
+
+    private DubboProtocPlugin buildDubboProtocPlugin(String dubboVersion, 
String dubboGenerateType, File protocPluginDirectory) {
+        DubboProtocPlugin dubboProtocPlugin = new DubboProtocPlugin();
+        DubboGenerateTypeEnum dubboGenerateTypeEnum = 
DubboGenerateTypeEnum.getByType(dubboGenerateType);
+        if (dubboGenerateTypeEnum == null) {
+            throw new RuntimeException(" can not find the dubboGenerateType: " 
+ dubboGenerateType + ",please check it !");
+        }
+        dubboProtocPlugin.setId(dubboGenerateType);
+        dubboProtocPlugin.setMainClass(dubboGenerateTypeEnum.getMainClass());
+        dubboProtocPlugin.setDubboVersion(dubboVersion);
+        dubboProtocPlugin.setPluginDirectory(protocPluginDirectory);
+        dubboProtocPlugin.setJavaHome(System.getProperty("java.home"));
+        DubboProtocPluginWrapper protocPluginWrapper = 
dubboProtocPluginWrapperFactory.findByOs();
+        dubboProtocPlugin.setResolvedJars(resolvePluginDependencies());
+        File protocPlugin = 
protocPluginWrapper.createProtocPlugin(dubboProtocPlugin, getLog());
+        boolean debugEnabled = getLog().isDebugEnabled();
+        if (debugEnabled) {
+            getLog().debug("protocPlugin: " + protocPlugin.getAbsolutePath());
+        }
+        dubboProtocPlugin.setProtocPlugin(protocPlugin);
+        return dubboProtocPlugin;
+    }
+
+    private List<File> resolvePluginDependencies() {
+        List<File> resolvedJars = new ArrayList<>();
+        final VersionRange versionSpec;
+        try {
+            versionSpec = VersionRange.createFromVersionSpec(dubboVersion);
+        } catch (InvalidVersionSpecificationException e) {
+            throw new RuntimeException("Invalid plugin version specification", 
e);
+        }
+        final Artifact protocPluginArtifact =
+            artifactFactory.createDependencyArtifact(
+                "org.apache.dubbo",
+                "dubbo-compiler",
+                versionSpec,
+                "jar",
+                "",
+                Artifact.SCOPE_RUNTIME);
+        final ArtifactResolutionRequest request = new 
ArtifactResolutionRequest()
+            .setArtifact(project.getArtifact())
+            .setResolveRoot(false)
+            
.setArtifactDependencies(Collections.singleton(protocPluginArtifact))
+            .setManagedVersionMap(emptyMap())
+            .setLocalRepository(localRepository)
+            .setRemoteRepositories(remoteRepositories)
+            .setOffline(session.isOffline())
+            .setForceUpdate(session.getRequest().isUpdateSnapshots())
+            .setServers(session.getRequest().getServers())
+            .setMirrors(session.getRequest().getMirrors())
+            .setProxies(session.getRequest().getProxies());
+
+        final ArtifactResolutionResult result = 
repositorySystem.resolve(request);
+
+        try {
+            resolutionErrorHandler.throwErrors(request, result);
+        } catch (ArtifactResolutionException e) {
+            throw new RuntimeException("Unable to resolve plugin artifact: " + 
e.getMessage(), e);
+        }
+
+        final Set<Artifact> artifacts = result.getArtifacts();
+
+        if (artifacts == null || artifacts.isEmpty()) {
+            throw new RuntimeException("Unable to resolve plugin artifact");
+        }
+
+        for (final Artifact artifact : artifacts) {
+            resolvedJars.add(artifact.getFile());
+        }
+
+        if (getLog().isDebugEnabled()) {
+            getLog().debug("Resolved jars: " + resolvedJars);
+        }
+        return resolvedJars;
+    }
+
+    protected Artifact createProtocArtifact(final String artifactSpec) {
+        final String[] parts = artifactSpec.split(":");
+        if (parts.length < 3 || parts.length > 5) {
+            throw new RuntimeException(
+                "Invalid artifact specification format"
+                    + ", expected: 
groupId:artifactId:version[:type[:classifier]]"
+                    + ", actual: " + artifactSpec);
+        }
+        final String type = parts.length >= 4 ? parts[3] : "exe";
+        final String classifier = parts.length == 5 ? parts[4] : null;
+        //parts: [com.google.protobuf, protoc, 3.6.0, exe, osx-x86_64]
+        getLog().info("parts: " + Arrays.toString(parts));
+        return createDependencyArtifact(parts[0], parts[1], parts[2], type, 
classifier);
+    }
+
+    protected Artifact createDependencyArtifact(
+        final String groupId,
+        final String artifactId,
+        final String version,
+        final String type,
+        final String classifier
+    ) {
+        final VersionRange versionSpec;
+        try {
+            versionSpec = VersionRange.createFromVersionSpec(version);
+        } catch (final InvalidVersionSpecificationException e) {
+            throw new RuntimeException("Invalid version specification", e);
+        }
+        return artifactFactory.createDependencyArtifact(
+            groupId,
+            artifactId,
+            versionSpec,
+            type,
+            classifier,
+            Artifact.SCOPE_RUNTIME);
+    }
+
+    protected File resolveBinaryArtifact(final Artifact artifact) {
+        final ArtifactResolutionResult result;
+        final ArtifactResolutionRequest request = new 
ArtifactResolutionRequest()
+            .setArtifact(project.getArtifact())
+            .setResolveRoot(false)
+            .setResolveTransitively(false)
+            .setArtifactDependencies(singleton(artifact))
+            .setManagedVersionMap(emptyMap())
+            .setLocalRepository(localRepository)
+            .setRemoteRepositories(remoteRepositories)
+            .setOffline(session.isOffline())
+            .setForceUpdate(session.getRequest().isUpdateSnapshots())
+            .setServers(session.getRequest().getServers())
+            .setMirrors(session.getRequest().getMirrors())
+            .setProxies(session.getRequest().getProxies());
+        result = repositorySystem.resolve(request);
+        try {
+            resolutionErrorHandler.throwErrors(request, result);
+        } catch (final ArtifactResolutionException e) {
+            throw new RuntimeException("Unable to resolve artifact: " + 
e.getMessage(), e);
+        }
+
+        final Set<Artifact> artifacts = result.getArtifacts();
+
+        if (artifacts == null || artifacts.isEmpty()) {
+            throw new RuntimeException("Unable to resolve artifact");
+        }
+
+        final Artifact resolvedBinaryArtifact = artifacts.iterator().next();
+        if (getLog().isDebugEnabled()) {
+            getLog().debug("Resolved artifact: " + resolvedBinaryArtifact);
+        }
+
+        final File sourceFile = resolvedBinaryArtifact.getFile();
+        final String sourceFileName = sourceFile.getName();
+        final String targetFileName;
+        if (Os.isFamily(Os.FAMILY_WINDOWS) && 
!sourceFileName.endsWith(".exe")) {
+            targetFileName = sourceFileName + ".exe";
+        } else {
+            targetFileName = sourceFileName;
+        }
+        final File targetFile = new File(protocPluginDirectory, 
targetFileName);
+        if (targetFile.exists()) {
+            getLog().debug("Executable file already exists: " + 
targetFile.getAbsolutePath());
+            return targetFile;
+        }
+        try {
+            FileUtils.forceMkdir(protocPluginDirectory);
+        } catch (final IOException e) {
+            throw new RuntimeException("Unable to create directory " + 
protocPluginDirectory, e);
+        }
+        try {
+            FileUtils.copyFile(sourceFile, targetFile);
+        } catch (final IOException e) {
+            throw new RuntimeException("Unable to copy the file to " + 
protocPluginDirectory, e);
+        }
+        if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
+            boolean b = targetFile.setExecutable(true);
+            if (!b) {
+                throw new RuntimeException("Unable to make executable: " + 
targetFile.getAbsolutePath());
+            }
+        }
+
+        if (getLog().isDebugEnabled()) {
+            getLog().debug("Executable file: " + targetFile.getAbsolutePath());
+        }
+        return targetFile;
+    }
+
+
+    public String getError() {
+        return fixUnicodeOutput(error.getOutput());
+    }
+
+    public String getOutput() {
+        return fixUnicodeOutput(output.getOutput());
+    }
+
+    private static String fixUnicodeOutput(final String message) {
+        return new String(message.getBytes(), StandardCharsets.UTF_8);
+    }
+}
diff --git 
a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocPlugin.java
 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocPlugin.java
new file mode 100644
index 0000000000..630390bc18
--- /dev/null
+++ 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocPlugin.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.maven.plugin.protoc;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DubboProtocPlugin {
+
+    private String id;
+    private String mainClass;
+    private String dubboVersion;
+    private String javaHome;
+    private File pluginDirectory;
+    private List<File> resolvedJars = new ArrayList<>();
+    private List<String> args = new ArrayList<>();
+    private List<String> jvmArgs = new ArrayList<>();
+    private File protocPlugin = null;
+
+    public DubboProtocPlugin() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getMainClass() {
+        return mainClass;
+    }
+
+    public void setMainClass(String mainClass) {
+        this.mainClass = mainClass;
+    }
+
+    public String getDubboVersion() {
+        return dubboVersion;
+    }
+
+    public void setDubboVersion(String dubboVersion) {
+        this.dubboVersion = dubboVersion;
+    }
+
+    public String getJavaHome() {
+        return javaHome;
+    }
+
+    public void setJavaHome(String javaHome) {
+        this.javaHome = javaHome;
+    }
+
+    public File getPluginDirectory() {
+        return pluginDirectory;
+    }
+
+    public void setPluginDirectory(File pluginDirectory) {
+        this.pluginDirectory = pluginDirectory;
+    }
+
+    public List<File> getResolvedJars() {
+        return resolvedJars;
+    }
+
+    public void setResolvedJars(List<File> resolvedJars) {
+        this.resolvedJars = resolvedJars;
+    }
+
+    public void addResolvedJar(File jar) {
+        resolvedJars.add(jar);
+    }
+
+    public List<String> getArgs() {
+        return args;
+    }
+
+    public void setArgs(List<String> args) {
+        this.args = args;
+    }
+
+    public void addArg(String arg) {
+        args.add(arg);
+    }
+
+    public List<String> getJvmArgs() {
+        return jvmArgs;
+    }
+
+    public void setJvmArgs(List<String> jvmArgs) {
+        this.jvmArgs = jvmArgs;
+    }
+
+    public void addJvmArg(String jvmArg) {
+        jvmArgs.add(jvmArg);
+    }
+
+    public String getPluginName() {
+        return "protoc-gen-" + id;
+    }
+
+    public File getProtocPlugin() {
+        return protocPlugin;
+    }
+
+    public void setProtocPlugin(File protocPlugin) {
+        this.protocPlugin = protocPlugin;
+    }
+
+    @Override
+    public String toString() {
+        return "DubboProtocPlugin{" +
+            "id='" + id + '\'' +
+            ", mainClass='" + mainClass + '\'' +
+            ", dubboVersion='" + dubboVersion + '\'' +
+            ", javaHome='" + javaHome + '\'' +
+            ", pluginDirectory=" + pluginDirectory +
+            ", resolvedJars=" + resolvedJars +
+            ", args=" + args +
+            ", jvmArgs=" + jvmArgs +
+            ", protocPlugin=" + protocPlugin +
+            '}';
+    }
+}
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocPluginWrapper.java
similarity index 58%
copy from 
dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
copy to 
dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocPluginWrapper.java
index 1abf2a0064..0124f9e4fa 100644
--- 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
+++ 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocPluginWrapper.java
@@ -14,29 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.gen.dubbo;
+package org.apache.dubbo.maven.plugin.protoc;
 
-import org.apache.dubbo.gen.AbstractGenerator;
+import org.apache.maven.plugin.logging.Log;
 
-import com.salesforce.jprotoc.ProtocPlugin;
+import java.io.File;
 
-public class DubboGenerator extends AbstractGenerator {
+public interface DubboProtocPluginWrapper {
 
-    public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new DubboGenerator());
-        } else {
-            ProtocPlugin.debug(new DubboGenerator(), args[0]);
-        }
-    }
-
-    @Override
-    protected String getClassPrefix() {
-        return "";
-    }
-
-    @Override
-    protected String getClassSuffix() {
-        return "Dubbo";
-    }
+    File createProtocPlugin(DubboProtocPlugin dubboProtocPlugin, Log log);
 }
diff --git 
a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocPluginWrapperFactory.java
 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocPluginWrapperFactory.java
new file mode 100644
index 0000000000..3a60034b63
--- /dev/null
+++ 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocPluginWrapperFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.maven.plugin.protoc;
+
+
+import org.codehaus.plexus.util.Os;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class DubboProtocPluginWrapperFactory {
+
+    private final LinuxDubboProtocPluginWrapper linuxProtocCommandBuilder = 
new LinuxDubboProtocPluginWrapper();
+    private final WinDubboProtocPluginWrapper winDubboProtocPluginWrapper = 
new WinDubboProtocPluginWrapper();
+
+
+    private final Map<String, DubboProtocPluginWrapper> 
dubboProtocPluginWrappers = new HashMap<>();
+
+
+    public DubboProtocPluginWrapperFactory() {
+        dubboProtocPluginWrappers.put("linux", linuxProtocCommandBuilder);
+        dubboProtocPluginWrappers.put("windows", winDubboProtocPluginWrapper);
+    }
+
+
+    public DubboProtocPluginWrapper findByOs() {
+        if (Os.isFamily(Os.FAMILY_WINDOWS)) {
+            return dubboProtocPluginWrappers.get("windows");
+        }
+        return dubboProtocPluginWrappers.get("linux");
+    }
+}
diff --git 
a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/LinuxDubboProtocPluginWrapper.java
 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/LinuxDubboProtocPluginWrapper.java
new file mode 100644
index 0000000000..639300eb33
--- /dev/null
+++ 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/LinuxDubboProtocPluginWrapper.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.maven.plugin.protoc;
+
+import org.apache.maven.plugin.logging.Log;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+public class LinuxDubboProtocPluginWrapper implements DubboProtocPluginWrapper 
{
+
+
+    @Override
+    public File createProtocPlugin(DubboProtocPlugin dubboProtocPlugin, Log 
log) {
+        List<File> resolvedJars = dubboProtocPlugin.getResolvedJars();
+        createPluginDirectory(dubboProtocPlugin.getPluginDirectory());
+        File pluginExecutableFile = new 
File(dubboProtocPlugin.getPluginDirectory(), dubboProtocPlugin.getPluginName());
+        final File javaLocation = new File(dubboProtocPlugin.getJavaHome(), 
"bin/java");
+
+        if (log.isDebugEnabled()) {
+            log.debug("javaLocation=" + javaLocation.getAbsolutePath());
+        }
+        try (final PrintWriter out = new PrintWriter(new 
FileWriter(pluginExecutableFile))) {
+            out.println("#!/bin/sh");
+            out.println();
+            out.print("CP=");
+            for (int i = 0; i < resolvedJars.size(); i++) {
+                if (i > 0) {
+                    out.print(":");
+                }
+                out.print("\"" + resolvedJars.get(i).getAbsolutePath() + "\"");
+            }
+            out.println();
+            out.print("ARGS=\"");
+            for (final String arg : dubboProtocPlugin.getArgs()) {
+                out.print(arg + " ");
+            }
+            out.println("\"");
+            out.print("JVMARGS=\"");
+            for (final String jvmArg : dubboProtocPlugin.getJvmArgs()) {
+                out.print(jvmArg + " ");
+            }
+            out.println("\"");
+            out.println();
+            out.println("\"" + javaLocation.getAbsolutePath() + "\" $JVMARGS 
-cp $CP "
+                + dubboProtocPlugin.getMainClass() + " $ARGS");
+            out.println();
+            boolean b = pluginExecutableFile.setExecutable(true);
+            if (!b) {
+                throw new RuntimeException("Could not make plugin executable: 
" + pluginExecutableFile);
+            }
+            return pluginExecutableFile;
+        } catch (IOException e) {
+            throw new RuntimeException("Could not write plugin script file: " 
+ pluginExecutableFile, e);
+        }
+
+    }
+
+
+    private void createPluginDirectory(File pluginDirectory) {
+        pluginDirectory.mkdirs();
+        if (!pluginDirectory.isDirectory()) {
+            throw new RuntimeException("Could not create protoc plugin 
directory: "
+                + pluginDirectory.getAbsolutePath());
+        }
+    }
+}
diff --git 
a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/ProtocMetaData.java
 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/ProtocMetaData.java
new file mode 100644
index 0000000000..277d53b481
--- /dev/null
+++ 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/ProtocMetaData.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.maven.plugin.protoc;
+
+
+import java.io.File;
+import java.util.List;
+
+public class ProtocMetaData {
+
+    private String protocExecutable;
+    private File protoSourceDir;
+    private List<File> protoFiles;
+    private File outputDir;
+    private DubboProtocPlugin dubboProtocPlugin;
+
+    public ProtocMetaData() {
+
+    }
+
+    public ProtocMetaData(String protocExecutable, File protoSourceDir, 
List<File> protoFiles, File outputDir, DubboProtocPlugin dubboProtocPlugin) {
+        this.protocExecutable = protocExecutable;
+        this.protoSourceDir = protoSourceDir;
+        this.protoFiles = protoFiles;
+        this.outputDir = outputDir;
+        this.dubboProtocPlugin = dubboProtocPlugin;
+    }
+
+
+    public String getProtocExecutable() {
+        return protocExecutable;
+    }
+
+    public void setProtocExecutable(String protocExecutable) {
+        this.protocExecutable = protocExecutable;
+    }
+
+    public File getProtoSourceDir() {
+        return protoSourceDir;
+    }
+
+    public void setProtoSourceDir(File protoSourceDir) {
+        this.protoSourceDir = protoSourceDir;
+    }
+
+    public List<File> getProtoFiles() {
+        return protoFiles;
+    }
+
+    public void setProtoFiles(List<File> protoFiles) {
+        this.protoFiles = protoFiles;
+    }
+
+    public File getOutputDir() {
+        return outputDir;
+    }
+
+    public void setOutputDir(File outputDir) {
+        this.outputDir = outputDir;
+    }
+
+    public DubboProtocPlugin getDubboProtocPlugin() {
+        return dubboProtocPlugin;
+    }
+
+    public void setDubboProtocPlugin(DubboProtocPlugin dubboProtocPlugin) {
+        this.dubboProtocPlugin = dubboProtocPlugin;
+    }
+
+
+}
diff --git 
a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/WinDubboProtocPluginWrapper.java
 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/WinDubboProtocPluginWrapper.java
new file mode 100644
index 0000000000..f28a8c5c9f
--- /dev/null
+++ 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/WinDubboProtocPluginWrapper.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.maven.plugin.protoc;
+
+import org.apache.maven.plugin.logging.Log;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URL;
+
+public class WinDubboProtocPluginWrapper implements DubboProtocPluginWrapper {
+
+    private static final String DATA_MODEL_SYSPROP = "sun.arch.data.model";
+
+    private static final String WIN_JVM_DATA_MODEL_32 = "32";
+
+    private static final String WIN_JVM_DATA_MODEL_64 = "64";
+
+    private String winJvmDataModel;
+
+    private static File findJvmLocation(final File javaHome, final String... 
paths) {
+        for (final String path : paths) {
+            final File jvmLocation = new File(javaHome, path);
+            if (jvmLocation.isFile()) {
+                return jvmLocation;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public File createProtocPlugin(DubboProtocPlugin dubboProtocPlugin, Log 
log) {
+        createPluginDirectory(dubboProtocPlugin.getPluginDirectory());
+        final File javaHome = new File(dubboProtocPlugin.getJavaHome());
+        final File jvmLocation = findJvmLocation(javaHome,
+            "jre/bin/server/jvm.dll",
+            "bin/server/jvm.dll",
+            "jre/bin/client/jvm.dll",
+            "bin/client/jvm.dll");
+        final File winRun4JIniFile = new 
File(dubboProtocPlugin.getPluginDirectory(), dubboProtocPlugin.getId() + 
".ini");
+
+        if (winJvmDataModel != null) {
+            if (!(winJvmDataModel.equals(WIN_JVM_DATA_MODEL_32) || 
winJvmDataModel.equals(WIN_JVM_DATA_MODEL_64))) {
+                throw new RuntimeException("winJvmDataModel must be '32' or 
'64'");
+            }
+        } else if (archDirectoryExists("amd64", 
dubboProtocPlugin.getJavaHome())) {
+            winJvmDataModel = WIN_JVM_DATA_MODEL_64;
+            if (log.isDebugEnabled()) {
+                log.debug("detected 64-bit JVM from directory structure");
+            }
+        } else if (archDirectoryExists("i386", 
dubboProtocPlugin.getJavaHome())) {
+            winJvmDataModel = WIN_JVM_DATA_MODEL_32;
+            if (log.isDebugEnabled()) {
+                log.debug("detected 32-bit JVM from directory structure");
+            }
+        } else if (System.getProperty(DATA_MODEL_SYSPROP) != null) {
+            winJvmDataModel = System.getProperty(DATA_MODEL_SYSPROP);
+            if (log.isDebugEnabled()) {
+                log.debug("detected " + winJvmDataModel + "-bit JVM from 
system property " + DATA_MODEL_SYSPROP);
+            }
+        } else {
+            winJvmDataModel = WIN_JVM_DATA_MODEL_32;
+            if (log.isDebugEnabled()) {
+                log.debug("defaulting to 32-bit JVM");
+            }
+        }
+        try (final PrintWriter out = new PrintWriter(new 
FileWriter(winRun4JIniFile))) {
+            if (jvmLocation != null) {
+                out.println("vm.location=" + jvmLocation.getAbsolutePath());
+            }
+            int index = 1;
+            for (final File resolvedJar : dubboProtocPlugin.getResolvedJars()) 
{
+                out.println("classpath." + index + "=" + 
resolvedJar.getAbsolutePath());
+                index++;
+            }
+            out.println("main.class=" + dubboProtocPlugin.getMainClass());
+
+            index = 1;
+            for (final String arg : dubboProtocPlugin.getArgs()) {
+                out.println("arg." + index + "=" + arg);
+                index++;
+            }
+
+            index = 1;
+            for (final String jvmArg : dubboProtocPlugin.getJvmArgs()) {
+                out.println("vmarg." + index + "=" + jvmArg);
+                index++;
+            }
+
+            out.println("vm.version.min=1.8");
+            out.println("log.level=none");
+            out.println("[ErrorMessages]");
+            out.println("show.popup=false");
+        } catch (IOException e) {
+            throw new RuntimeException(
+                "Could not write WinRun4J ini file: " + 
winRun4JIniFile.getAbsolutePath(), e);
+        }
+        final String executablePath = getWinrun4jExecutablePath();
+        final URL url = 
Thread.currentThread().getContextClassLoader().getResource(executablePath);
+        if (url == null) {
+            throw new RuntimeException(
+                "Could not locate WinRun4J executable at path: " + 
executablePath);
+        }
+        File pluginExecutableFile = getPluginExecutableFile(dubboProtocPlugin);
+        try {
+            FileUtils.copyURLToFile(url, pluginExecutableFile);
+            return pluginExecutableFile;
+        } catch (IOException e) {
+            throw new RuntimeException(
+                "Could not copy WinRun4J executable to: " + 
pluginExecutableFile.getAbsolutePath(), e);
+        }
+    }
+
+    private void createPluginDirectory(File pluginDirectory) {
+        pluginDirectory.mkdirs();
+        if (!pluginDirectory.isDirectory()) {
+            throw new RuntimeException("Could not create protoc plugin 
directory: "
+                + pluginDirectory.getAbsolutePath());
+        }
+    }
+
+    private boolean archDirectoryExists(String arch, String javaHome) {
+        return javaHome != null
+            && (new File(javaHome, "jre/lib/" + arch).isDirectory()
+            || new File(javaHome, "lib/" + arch).isDirectory());
+    }
+
+    private String getWinrun4jExecutablePath() {
+        return "winrun4j/WinRun4J" + winJvmDataModel + ".exe";
+    }
+
+    public File getPluginExecutableFile(DubboProtocPlugin dubboProtocPlugin) {
+        return new File(dubboProtocPlugin.getPluginDirectory(), "protoc-gen-" 
+ dubboProtocPlugin.getId() + ".exe");
+    }
+
+}
diff --git 
a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/command/DefaultProtocCommandBuilder.java
 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/command/DefaultProtocCommandBuilder.java
new file mode 100644
index 0000000000..c5ef8b4282
--- /dev/null
+++ 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/command/DefaultProtocCommandBuilder.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.maven.plugin.protoc.command;
+
+import org.apache.dubbo.maven.plugin.protoc.DubboProtocPlugin;
+import org.apache.dubbo.maven.plugin.protoc.ProtocMetaData;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DefaultProtocCommandBuilder implements ProtocCommandArgsBuilder {
+
+    @Override
+    public List<String> buildProtocCommandArgs(ProtocMetaData protocMetaData) {
+        final List<String> command = new ArrayList<>();
+        command.add("--proto_path=" + protocMetaData.getProtoSourceDir());
+        String outputOption = "--java_out=";
+        outputOption += protocMetaData.getOutputDir();
+        command.add(outputOption);
+        DubboProtocPlugin dubboProtocPlugin = 
protocMetaData.getDubboProtocPlugin();
+        command.add("--plugin=protoc-gen-" + dubboProtocPlugin.getId() + '=' + 
dubboProtocPlugin.getProtocPlugin());
+        command.add("--" + dubboProtocPlugin.getId() + "_out=" + 
protocMetaData.getOutputDir());
+        for (final File protoFile : protocMetaData.getProtoFiles()) {
+            command.add(protoFile.toString());
+        }
+        return command;
+    }
+}
diff --git 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/command/ProtocCommandArgsBuilder.java
similarity index 58%
copy from 
dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
copy to 
dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/command/ProtocCommandArgsBuilder.java
index 1abf2a0064..f00de41379 100644
--- 
a/dubbo-compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
+++ 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/command/ProtocCommandArgsBuilder.java
@@ -14,29 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.gen.dubbo;
+package org.apache.dubbo.maven.plugin.protoc.command;
 
-import org.apache.dubbo.gen.AbstractGenerator;
+import org.apache.dubbo.maven.plugin.protoc.ProtocMetaData;
 
-import com.salesforce.jprotoc.ProtocPlugin;
+import java.util.List;
 
-public class DubboGenerator extends AbstractGenerator {
+public interface ProtocCommandArgsBuilder {
 
-    public static void main(String[] args) {
-        if (args.length == 0) {
-            ProtocPlugin.generate(new DubboGenerator());
-        } else {
-            ProtocPlugin.debug(new DubboGenerator(), args[0]);
-        }
-    }
-
-    @Override
-    protected String getClassPrefix() {
-        return "";
-    }
-
-    @Override
-    protected String getClassSuffix() {
-        return "Dubbo";
-    }
+    List<String> buildProtocCommandArgs(ProtocMetaData protocMetaData) throws 
RuntimeException;
 }
diff --git 
a/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/enums/DubboGenerateTypeEnum.java
 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/enums/DubboGenerateTypeEnum.java
new file mode 100644
index 0000000000..2157e6eee1
--- /dev/null
+++ 
b/dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/enums/DubboGenerateTypeEnum.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.maven.plugin.protoc.enums;
+
+public enum DubboGenerateTypeEnum {
+    Dubbo("dubbo","org.apache.dubbo.gen.dubbo.DubboGenerator"),
+    Dubbo3("dubbo3","org.apache.dubbo.gen.dubbo.Dubbo3Generator"),
+    Tri("tri","org.apache.dubbo.gen.tri.Dubbo3TripleGenerator"),
+    
Tri_reactor("tri_reactor","org.apache.dubbo.gen.tri.reactive.ReactorDubbo3TripleGenerator"),
+    Grpc("grpc","org.apache.dubbo.gen.grpc.DubboGrpcGenerator"),
+    
Grpc_reactor("grpc_reactor","org.apache.dubbo.gen.grpc.reactive.ReactorDubboGrpcGenerator"),
+    
Grpc_rx("grpc_rx","org.apache.dubbo.gen.grpc.reactive.RxDubboGrpcGenerator"),
+    ;
+    private String id;
+    private String mainClass;
+    DubboGenerateTypeEnum(String id, String mainClass) {
+        this.id = id;
+        this.mainClass = mainClass;
+    }
+
+    public static DubboGenerateTypeEnum getByType(String dubboGenerateType) {
+        DubboGenerateTypeEnum[] values = DubboGenerateTypeEnum.values();
+        for (DubboGenerateTypeEnum value : values) {
+            if (value.getId().equals(dubboGenerateType)) {
+                return value;
+            }
+        }
+        return null;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getMainClass() {
+        return mainClass;
+    }
+
+    public void setMainClass(String mainClass) {
+        this.mainClass = mainClass;
+    }
+}
diff --git a/pom.xml b/pom.xml
index 63b42414c3..846ad34ec6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -367,6 +367,8 @@
                                         
**/org/apache/dubbo/metrics/aggregate/DubboAbstractTDigest.java,
                                         
**/org/apache/dubbo/common/logger/helpers/FormattingTuple.java,
                                         
**/org/apache/dubbo/common/logger/helpers/MessageFormatter.java,
+                                        
**/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java,
+                                        
**/org/apache/dubbo/gen/utils/ProtoTypeMap.java,
                                         **/istio/v1/auth/**/*,
                                         **/com/google/rpc/*,
                                         **/generated/**/*,

Reply via email to