首页 > 解决方案 > 带有 Maven 的 Xtend 不保留语义

问题描述

我尝试在一个学生项目中使用 Xtend 和 Xcore。为此,我配置了一个带有依赖项的 Maven 项目,以在 Mavengenerate-sources阶段生成 xtend/xcore 源。valXtend 类和 Xcore 模型可以很好地编译为 Java,但是当我执行mvn clean generate-sources命令时,try-with-resource 中的 Xtend 常量 () 似乎没有编译为 Java 中的最终变量。但是,当 Eclipse 编译 xtend/xcore 类时,并没有出现这个问题。我在一个最小的项目中重现了这个问题:

酒吧 Xtend 类:

class Bar {
    
    def static void main(String... args) {
        try(val foo = new BufferedInputStream(System.in)) {
            val bar = [| bar(foo)]
            bar.apply
        }
    }
    
    def static void bar(BufferedInputStream bis) {
        System.out.println(new BufferedReader((new InputStreamReader(bis))).lines().collect(Collectors.joining("\n")))
    }
    
}

Maven的产品代码:

public class Bar {
  public static void main(final String... args) {
    try {
      List<Throwable> _ts = new ArrayList<Throwable>();
      BufferedInputStream foo = null;
      try {
        foo = new BufferedInputStream(System.in);
        final Procedure0 _function = new Procedure0() {
          public void apply() {
            Bar.bar(foo);
          }
        };
        final Procedure0 bar = _function;
        bar.apply();
      } finally {
        if (foo != null) {
          try {
            foo.close();
          } catch (Throwable _t) {
            _ts.add(_t);
          }
        }
        if(!_ts.isEmpty()) throw Exceptions.sneakyThrow(_ts.get(0));
      }
    } catch (Throwable _e) {
      throw Exceptions.sneakyThrow(_e);
    }
  }
  
  public static void bar(final BufferedInputStream bis) {
    InputStreamReader _inputStreamReader = new InputStreamReader(bis);
    System.out.println(new BufferedReader(_inputStreamReader).lines().collect(Collectors.joining("\n")));
  }
}

产品代码有编译错误。确实,第 10 ( Bar.bar(foo);) 行, throw Local variable foo defined in an enclosing scope must be final or effectively final

比较一下,Eclipse 的产品代码:

@SuppressWarnings("all")
public class Bar {
  public static void main(final String... args) {
    try {
      try (final BufferedInputStream foo = new BufferedInputStream(System.in)) {
        final Procedure0 _function = () -> {
          Bar.bar(foo);
        };
        final Procedure0 bar = _function;
        bar.apply();
      }
    } catch (Throwable _e) {
      throw Exceptions.sneakyThrow(_e);
    }
  }
  
  public static void bar(final BufferedInputStream bis) {
    InputStreamReader _inputStreamReader = new InputStreamReader(bis);
    System.out.println(new BufferedReader(_inputStreamReader).lines().collect(Collectors.joining("\n")));
  }
}

我的印象是 Maven 不会编译为 Java 8 代码,但我想我在 pom.xml 中设置了版本。

我用于最小项目的 pom.xml:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>fr.theogiraudet</groupId>
    <version>1.0.0-SNAPSHOT</version>
    <artifactId>fr.theogiraudet.foo</artifactId>

    <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>

        <core-resources-version>3.7.100</core-resources-version>
        <emf-version>2.23.0</emf-version>
        <emf-common-version>2.21.0</emf-common-version>
        <xtext-version>2.24.0</xtext-version>
        <ecore-xtext-version>1.5.0</ecore-xtext-version>
        <ecore-xcore-version>1.16.0</ecore-xcore-version>
        <ecore-xcore-lib-version>1.5.0</ecore-xcore-lib-version>
        
        <xtend-path>${basedir}/src/main/xtend</xtend-path>
        <xcore-path>${basedir}/model</xcore-path>
        <xtend-gen-path>${basedir}/src/main/javagen</xtend-gen-path>
        <xcore-gen-path>${basedir}/src/main/javagen</xcore-gen-path>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.eclipse.emf</groupId>
            <artifactId>org.eclipse.emf.common</artifactId>
            <version>${emf-common-version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.emf</groupId>
            <artifactId>org.eclipse.emf.ecore</artifactId>
            <version>${emf-version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.emf</groupId>
            <artifactId>org.eclipse.emf.ecore.xcore.lib</artifactId>
            <version>${ecore-xcore-lib-version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.xtext</groupId>
            <artifactId>org.eclipse.xtext.xbase.lib</artifactId>
            <version>${xtext-version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.xtend</groupId>
            <artifactId>org.eclipse.xtend.lib</artifactId>
            <version>${xtext-version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.emf</groupId>
            <artifactId>org.eclipse.emf.ecore.xmi</artifactId>
            <version>2.16.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
            </plugin>

            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>2.6.1</version>
                <configuration>
                    <filesets>
                        <fileset>
                            <excludes>
                                <exclude>.dummy.txt</exclude>
                            </excludes>
                            <directory>${xtend-gen-path}</directory>
                        </fileset>
                        <fileset>
                            <excludes>
                                <exclude>.dummy.txt</exclude>
                            </excludes>
                            <directory>${xtend-gen-path}</directory>
                        </fileset>
                    </filesets>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>1.9.1</version>
                <executions>
                    <execution>
                        <id>add-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${xtend-gen-path}</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.eclipse.xtext</groupId>
                <artifactId>xtext-maven-plugin</artifactId>
                <version>${xtext-version}</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <languages>
                        <language>
                            <setup>org.eclipse.emf.codegen.ecore.xtext.GenModelSupport</setup>
                        </language>
                        <language>
                            <setup>org.eclipse.xtend.core.XtendStandaloneSetup</setup>
                            <outputConfigurations>
                                <outputConfiguration>
                                    <outputDirectory>${xtend-gen-path}</outputDirectory>
                                </outputConfiguration>
                            </outputConfigurations>
                        </language>
                        <language>
                            <setup>org.eclipse.emf.ecore.xcore.XcoreStandaloneSetup</setup>
                            <outputConfigurations>
                                <outputConfiguration>
                                    <outputDirectory>${xcore-gen-path}</outputDirectory>
                                </outputConfiguration>
                            </outputConfigurations>

                        </language>
                    </languages>
                    <sourceRoots>
                        <root>${xtend-path}</root>
                        <root>${xcore-path}</root>
                    </sourceRoots>
                    <javaSourceVersion>1.8</javaSourceVersion>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.eclipse.core</groupId>
                        <artifactId>org.eclipse.core.resources</artifactId>
                        <version>${core-resources-version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.eclipse.xtend</groupId>
                        <artifactId>org.eclipse.xtend.core</artifactId>
                        <version>${xtext-version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.eclipse.emf</groupId>
                        <artifactId>org.eclipse.emf.codegen.ecore.xtext</artifactId>
                        <version>${ecore-xtext-version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.eclipse.emf</groupId>
                        <artifactId>org.eclipse.emf.ecore.xcore</artifactId>
                        <version>${ecore-xcore-version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.eclipse.emf</groupId>
                        <artifactId>org.eclipse.emf.ecore.xcore.lib</artifactId>
                        <version>${ecore-xcore-lib-version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

对于 Eclipse,我使用:

您可以在此处克隆最小项目: https ://github.com/theogiraudet/XtendMinimalProject.git

预先感谢您的帮助!

标签: javaeclipsemavenxtend

解决方案


推荐阅读