2017-02-21 7 views
14

एक मेवेन बिल्ड में, मैं गतिशील रूप से बाइट कोड जनरेशन लाइब्रेरी (बाइट बडी) का उपयोग करके कुछ जावा प्रकार उत्पन्न कर रहा हूं। स्वाभाविक रूप से, इन वर्ग फ़ाइलों में संबंधित स्रोत फ़ाइलें नहीं हैं। इस तरह से केवल कुछ कक्षाएं उत्पन्न की जाएंगी। इस परियोजना के लिए अधिकांश कोड जावा स्रोत होने जा रहा है। आदर्श रूप से, जावा स्रोत प्रतिबिंबित या रनटाइम कोड पीढ़ी का उपयोग करने के बजाय जनरेट किए गए प्रकारों को स्थिर तरीके से संदर्भित करेगा, जिसका अर्थ है कि कक्षाओं को जावैक के लिए संकलन वर्ग पथ पर होना आवश्यक है। क्या मैं एक ही मेवेन प्रोजेक्ट के लिए संकलित वर्ग पथ पर उत्पन्न वर्ग प्राप्त कर सकता हूं यानी एक अलग मेवेन परियोजना और आर्टिफैक्ट के बिना स्रोत कोड युक्त मेवेन प्रोजेक्ट द्वारा संदर्भित जेनरेट बाइट कोड को पकड़ने के लिए?क्या मैं एक ही मेवेन प्रोजेक्ट में स्रोत फ़ाइल में गतिशील रूप से उत्पन्न और संदर्भित कर सकता हूं?

अद्यतन: मैं पहले से ही, सीधे target/classes अर्थात project.build.outputDirectory में उत्पन्न कक्षाएं लगाने की कोशिश की है जल्दी में Maven बिल्ड जीवनचक्र है, लेकिन ऐसा लगता है कि वर्ग के रास्ते पर नहीं है। जेनरेट प्रकारों को मेवेन कंपाइलर प्लगइन या आईडीई द्वारा हल नहीं किया जा सका। मैंने जेनर क्लास युक्त target के तहत अतिरिक्त संसाधन निर्देशिका जोड़ने के लिए बिल्ड हेल्पर मेवेन प्लगइन का उपयोग करने का भी प्रयास किया, जिसे स्वचालित रूप से target/classes में कॉपी किया गया था। इस विन्यास ने एक ही समस्या का प्रदर्शन किया।

अद्यतन: मैं GitHub पर एक पूर्ण सार्वजनिक रेपो बनाया है:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <parent> 
     <groupId>demo</groupId> 
     <artifactId>demo</artifactId> 
     <version>1.0-SNAPSHOT</version> 
     <relativePath>../pom.xml</relativePath> 
    </parent> 

    <artifactId>demo-enhanced</artifactId> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-dependency-plugin</artifactId> 
       <executions> 
        <execution> 
         <phase>generate-resources</phase> 
         <goals> 
          <goal>unpack</goal> 
         </goals> 
         <configuration> 
          <artifactItems> 
           <artifactItem> 
            <groupId>demo</groupId> 
            <artifactId>demo-original</artifactId> 
            <version>${project.version}</version> 
            <overWrite>true</overWrite> 
            <outputDirectory>${project.build.outputDirectory}</outputDirectory> 
            <includes>**/*.class</includes> 
            <excludes>META-INF/</excludes> 
           </artifactItem> 
          </artifactItems> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
      <plugin> 
       <groupId>net.bytebuddy</groupId> 
       <artifactId>byte-buddy-maven-plugin</artifactId> 
       <executions> 
        <execution> 
         <phase>process-resources</phase> 
         <goals> 
          <goal>transform</goal> 
         </goals> 
         <configuration> 
          <initialization> 
           <entryPoint>net.bytebuddy.test.SimpleEntryPoint</entryPoint> 
           <groupId>demo</groupId> 
           <artifactId>demo-transformer</artifactId> 
          </initialization> 
          <transformations> 
           <transformation> 
            <plugin>net.bytebuddy.test.SimplePlugin</plugin> 
            <groupId>demo</groupId> 
            <artifactId>demo-transformer</artifactId> 
           </transformation> 
          </transformations> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 

</project> 
: https://github.com/mches/so-42376851

यहाँ परियोजना मैं स्थिर कक्षाओं कि बाइट कोड बढ़ाया वर्गों संदर्भित करना चाहते हैं के लिए Maven पोम है

और यहाँ जनक पोम है:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>demo</groupId> 
    <artifactId>demo</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>pom</packaging> 

    <modules> 
     <module>demo-original</module> 
     <module>demo-transformer</module> 
     <module>demo-enhanced</module> 
    </modules> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <maven.compiler.source>1.8</maven.compiler.source> 
     <maven.compiler.target>1.8</maven.compiler.target> 
     <byte-buddy.version>1.6.9</byte-buddy.version> 
    </properties> 

    <dependencyManagement> 
     <dependencies> 
      <dependency> 
       <groupId>net.bytebuddy</groupId> 
       <artifactId>byte-buddy</artifactId> 
       <version>${byte-buddy.version}</version> 
      </dependency> 
      <dependency> 
       <groupId>demo</groupId> 
       <artifactId>demo-original</artifactId> 
       <version>${project.version}</version> 
      </dependency> 
      <dependency> 
       <groupId>demo</groupId> 
       <artifactId>demo-transformer</artifactId> 
       <version>${project.version}</version> 
      </dependency> 
      <dependency> 
       <groupId>demo</groupId> 
       <artifactId>demo-enhanced</artifactId> 
       <version>${project.version}</version> 
      </dependency> 
     </dependencies> 
    </dependencyManagement> 

    <build> 
     <pluginManagement> 
      <plugins> 
       <plugin> 
        <groupId>net.bytebuddy</groupId> 
        <artifactId>byte-buddy-maven-plugin</artifactId> 
        <version>${byte-buddy.version}</version> 
       </plugin> 
      </plugins> 
     </pluginManagement> 
    </build> 

</project> 

foo/Bar.java (मूल स्रोत) :

package foo; 

public class Bar { 
} 

शुद्ध/bytebuddy/परीक्षण/SimplePlugin.java (बाइट कोड बढ़ाने):

package net.bytebuddy.test; 

import net.bytebuddy.build.Plugin; 
import net.bytebuddy.description.modifier.Visibility; 


import net.bytebuddy.description.type.TypeDescription; 
import net.bytebuddy.dynamic.DynamicType; 
import net.bytebuddy.implementation.FieldAccessor; 

public class SimplePlugin implements Plugin { 
    @Override 
    public boolean matches(TypeDescription target) { 
     return target.getName().equals("foo.Bar"); 
    } 

    @Override 
    public DynamicType.Builder<?> apply(DynamicType.Builder<?> builder, TypeDescription typeDescription) { 
     if (typeDescription.getTypeName().equals("foo.Bar")) { 
      builder = builder.defineField("qux", String.class, Visibility.PRIVATE) 
        .defineMethod("getQux", String.class, Visibility.PUBLIC) 
        .intercept(FieldAccessor.ofField("qux")) 
        .defineMethod("setQux", void.class, Visibility.PUBLIC) 
        .withParameter(String.class) 
        .intercept(FieldAccessor.ofField("qux")); 
     } 
     return builder; 
    } 
} 

foo/Baz.java (स्थिर स्रोत फ़ाइल गतिशील प्रकार को संदर्भित):

package foo; 

public class Baz { 
    private Bar bar = new Bar(); 

    public String getQuux() { 
     return bar.getQux(); 
    } 

    public void setQuux(String quux) { 
     bar.setQux(quux); 
    } 
} 

अद्यतन: मेवेन एक बाध्य कोड और स्थैतिक वर्ग स्रोत कोड के साथ समेकित मॉड्यूल को शामिल करने वाली संरचना को समझता प्रतीत होता है, प्रत्येक के लिए अलग मॉड्यूल के रूप में अच्छी तरह से, लेकिन आईडीई, इंटेलिजे और ग्रहण, मेवेन के तरीके के आधार पर किसी भी संरचना के लिए वर्ग पथ को समझने में विफल रहता है।

+0

शायद आप जैक्स-बी का एक स्रोत स्रोत कोड ले सकते हैं: xjc यह सिमिल करता है उत्पन्न स्रोत चरण – HRgiger

उत्तर

1

हाँ आप कर सकते हैं। अपनी कक्षाओं को प्री-कंपाइल चरण पर उत्पन्न करें और इसे एक लक्ष्य/कक्षा फ़ोल्डर में रखें।

+0

पर ar चीज मैंने मैवेन बिल्ड लाइफसाइक्ल में शुरुआती कक्षाओं को रखने की कोशिश की थी, लेकिन ऐसा लगता है कि 'लक्ष्य/कक्षाएं' ('project.build.outputDirectory') कक्षा पथ पर नहीं है। उत्पन्न प्रकारों को मेवेन कंपाइलर प्लगइन या आईडीई द्वारा हल नहीं किया जा सका। –

+1

@ मार्क वे क्लासपाथ पर हैं। आपने उन्हें किस चरण में 'लक्ष्य/कक्षा' में बनाया था? क्या आप वाकई सही पैकेज संरचना के साथ उत्पन्न होते हैं? क्या आपने _see_ को लॉग में जेनरेट किया था, या उस फ़ोल्डर में? – Tunaki

+0

@ टुनकी मैं 'जेनरेट-संसाधन' चरण में 'लक्षित/कक्षाओं' के लिए अप्रशिक्षित कक्षाएं निकालता हूं। मैं 'प्रक्रिया-संसाधन' चरण में कक्षाओं को बढ़ाता हूं। और तुम सही हो '--debug' के साथ चल रहे मेवेन ने 'क्लासपाथ एलिमेंट्स' में 'लक्ष्य/कक्षा' शामिल किया है। मेरी वर्तमान कॉन्फ़िगरेशन के साथ, मैं मैवेन को स्थिर वर्ग को संकलित करने में सक्षम हूं जो कि 'लक्ष्य/कक्षाओं' में मौजूद जेनरेट प्रकार का संदर्भ देता है और मैं देख सकता हूं कि कक्षा सही है, लेकिन आईडीई (इंटेलिजे और ग्रहण) नहीं है प्रतीत होता है कि जनरेटेड क्लास को पहचानने और स्थिर प्रकार पर स्रोत-स्तरीय त्रुटियों की रिपोर्ट (प्रतीक हल नहीं कर सकता)। –

4

बाइट बडी के साथ, आप क्लास फाइलें उत्पन्न कर रहे हैं, न कि स्रोत फाइलें। दुर्भाग्यवश, मेवेन केवल जेनरेट किए गए स्रोतों के बारे में जानता है, लेकिन जेनरेट की गई क्लास फाइलों के बारे में नहीं। इसलिए एक विशिष्ट मॉड्यूल बनाने के लिए सबसे आसान है।

यदि यह संभव नहीं है, तो आप उन्हें resources जैसे अपने मेवेन प्रोजेक्ट के किसी भी स्रोत फ़ोल्डर में कॉपी कर सकते हैं। कुछ आईडीई उन वर्गों को ढूंढते हैं और उनका इलाज करते हैं अगर आपने उन्हें अपने java फ़ोल्डर में रखा था लेकिन उन्हें .class के साथ फ़ाइलों को समाप्त करने के रूप में संकलित करने का प्रयास किए बिना।

+0

ऐसा लगता है कि मेवेन इस संरचना को समझता है, लेकिन आईडीई, इंटेलिजे और ग्रहण, इसे समझने में विफल रहता है। मैंने पाया कि स्थिर कक्षाओं को रखने के लिए एक अतिरिक्त मॉड्यूल तैयार करना, जो मेरे आश्चर्य के लिए बढ़ी कक्षाओं के साथ मॉड्यूल पर निर्भर करता है, ने एमईई की कक्षा मार्ग को समझने की क्षमता में सुधार नहीं किया जिस तरह से मैवेन इसे समझता है। –

1

यह मेरा आदर्श समाधान नहीं है, लेकिन एक विचार काम करने के लिए लगता है कि दो समझौता कर रही है:

  1. बढ़ाया बाइट कोड के लिए अलग Maven मॉड्यूल और स्थिर कक्षाओं का प्रयोग करें।
  2. स्थिर मेन्यू मॉड्यूल के रूप में उसी मैवेन रिएक्टर के निर्माण में वर्धित बाइट कोड मॉड्यूल का निर्माण न करें।

क्यों यह काम करने के लिए लगता है के रूप में:

जब IDEs अपनी परियोजना/मॉड्यूल विन्यास, Maven pom.xml फ़ाइलों के आधार पर उत्पन्न, वे निर्भरता में बढ़ाया बाइट कोड पर एक पुस्तकालय के रूप में लाता हूँ एक परियोजना/मॉड्यूल के बजाय/JAR। जेएआर स्थिर वर्ग मॉड्यूल के लिए आईडीई के वर्ग पथ पर समाप्त होता है और उन्नत वर्गों का समाधान किया जाता है।

बढ़ाया बाइट कोड मॉड्यूल के लिए

इंटेलीजे प्रोजेक्ट फाइल:

<?xml version="1.0" encoding="UTF-8"?> 
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> 
    <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false"> 
    <output url="file://$MODULE_DIR$/target/classes" /> 
    <output-test url="file://$MODULE_DIR$/target/test-classes" /> 
    <content url="file://$MODULE_DIR$"> 
     <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> 
     <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> 
     <excludeFolder url="file://$MODULE_DIR$/target" /> 
    </content> 
    <orderEntry type="inheritedJdk" /> 
    <orderEntry type="sourceFolder" forTests="false" /> 
    </component> 
</module> 

अलग में Maven मॉड्यूल के साथ इंटेलीजे प्रोजेक्ट फाइल बनाता है (त्रुटियों):

<?xml version="1.0" encoding="UTF-8"?> 
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> 
    <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false"> 
    <output url="file://$MODULE_DIR$/target/classes" /> 
    <output-test url="file://$MODULE_DIR$/target/test-classes" /> 
    <content url="file://$MODULE_DIR$"> 
     <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> 
     <excludeFolder url="file://$MODULE_DIR$/target" /> 
    </content> 
    <orderEntry type="inheritedJdk" /> 
    <orderEntry type="sourceFolder" forTests="false" /> 
    <orderEntry type="module" module-name="demo-enhanced" /> 
    </component> 
</module> 

इंटेलीजे परियोजना एक ही निर्माण में Maven मॉड्यूल के साथ फ़ाइल (कोई त्रुटि नहीं):

<?xml version="1.0" encoding="UTF-8"?> 
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> 
    <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false"> 
    <output url="file://$MODULE_DIR$/target/classes" /> 
    <output-test url="file://$MODULE_DIR$/target/test-classes" /> 
    <content url="file://$MODULE_DIR$"> 
     <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> 
     <excludeFolder url="file://$MODULE_DIR$/target" /> 
    </content> 
    <orderEntry type="inheritedJdk" /> 
    <orderEntry type="sourceFolder" forTests="false" /> 
    <orderEntry type="library" name="Maven: demo:demo-enhanced:1.0-SNAPSHOT" level="project" /> 
    </component> 
</module> 
संबंधित मुद्दे

 संबंधित मुद्दे