在Buildship中:我如何用一个内置的jar替换Gradle项目?

时间:2018-04-11 16:33:30

标签: java gradle scala-ide gradle-eclipse

我希望能够让Eclipse忽略一个Gradle项目,而是使用它的预构建版本。

背景

我有一个项目"解析器"用Scala写的,还有十几个用Java编写的。我的工具集中最薄弱的环节是Scala IDE。我用这个插件来编辑&编译Scala代码,但不幸的是它在混合语言项目中打破了Java(JDT)工具*。

  • 具体来说:调用层次结构缺少结果,搜索崩溃等等。此外,Scala IDE似乎已经失去了资金,这些问题听起来相当基础,所以我不会屏住呼吸来解决这些问题。

使用Maven(m2e)我有一个解决方法,我很满意:

  1. 构建为.jar放入我当地的.m2存储库:

    cd parser; mvn install
    
  2. 在Eclipse中,关闭"解析器"项目

  3. "就像魔法",m2e只是选择了最近安装的' .jar并用它代替已关闭的项目。

    一个很棒的答案是如何让Gradle做到这一点!

    然而,我所希望的只是满足这些的任何解决方案......

    要求

    1. 我可以在必要时(很少)打开项目parser, 通过Gradle命令行编辑和构建更改。 完成后我会关闭它。
    2. 其他项目使用我当地.m2 repo中的内置.jar。 (如果他们总是如此,那就很好。)
    3. 此更改不得影响不使用Eclipse的其他人
    4. (理想情况下)其他Eclipse用户可以使用此更改
    5. 途径

      @ lance-java有一个类似的问题good answer,其中包含一些一般性的建议。我认为我可以排除这些想法:

      根据lance-java#4的想法听起来很可行。释义...

      • "使用eclipse plugin [结合] Buildship,例如使用whenMerged挂钩调整生成的.classpath [所有Java项目]。"

        更新:[4月18日]:我采用这种方法hit a brick wall。 Buildship并没有将构建的.jar放到运行时类路径上。 (更新2:现在已经解决了 - 请参阅我的回答。)

      问题

      主要问题:我如何构建一个解决方案,这将实际工作&避免任何重大陷阱?

      请注意,项目本身有一些依赖项,特别是:

      dependencies {
        compile 'org.scala-lang:scala-library:2.12.4'
        compileOnly  'com.google.code.findbugs:jsr305:1.3.9'
        antlr 'org.antlr:antlr4:4.5.3'
      }
      

      所以一个子问题可能是:如何在不重复定义的情况下将这些引入其他项目? (如果这不能自动起作用。)

2 个答案:

答案 0 :(得分:0)

parser项目

您应该使用maven-publish任务

publishToMavenLocal插件
apply plugin: 'maven-publish'

group = 'your.company'
version = '1.0.0'

publishing {    
    publications {
        mavenJava(MavenPublication) {
            from components.java

            pom.withXml {
                def root = asNode()
                root.appendNode('name', 'Your parser project name')
                root.appendNode('description', 'Your parser project description')
            }
        }
    }
}

每次进行修改时,只需根据需要更改版本号,然后使用gradle publishToMavenLocal

在使用parser

的其他java项目中

只需使用parser作为常规依赖项:

repositories {
    mavenLocal()
    ...
}

compile 'your.company:parser:1.0.0'

如果我对你的情况的理解是好的,它应该可以解决问题。

答案 1 :(得分:0)

所以解决方案有点牵扯。在添加'maven-publish'以创建库之后,我实现了以下内容以强制Eclipse使用预构建的库:

subprojects {
    // Additional configuration to manipulate the Eclipse classpaths
    configurations {
        parserSubstitution
    }
    dependencies {
        parserSubstitution module("com.example:parser:${project.version}")
    }

    apply plugin: 'eclipse'
    eclipse {
        classpath {
        plusConfigurations += [ configurations.pseLangSubstitution ]
        file {
            whenMerged { cp ->

                // Get Gradle to add the depedency upon
                // parser-xxx.jar via 'plusConfigurations' above.
                // Then this here if we have a dependency on Project(':parser')
                //  - If so, remove it (completing the project -> jar substitution).
                //  - If not, remove the .jar dependency: it wasn't needed.
                def usesParser = entries.removeAll {
                    it instanceof ProjectDependency && it.path.startsWith('/parser')
                }
                def parserJar =
                    cp.entries.find { it instanceof Library && it.path.contains('parser-') }
                if (usesParser) {
                    // This trick stops Buildship deleting it from the runtime classpath
                    parserJar ?. entryAttributes ?. remove("gradle_used_by_scope")
                } else {
                    cp.entries.remove { parserJar }
                }
            }
        }
    }

所以这有两个部分:

  1. 使用' plusConfigurations'感觉有点圆了。我最终这样做是因为我无法看到如何直接构造class Library类路径条目。然而,很可能需要实现“瞬态依赖性”。无论如何正确。 (见问题的结尾。)
  2. Gradle开发人员在this discussion向我提供了停止Buildship从运行时类路径中移除.jar(因此偏离了Gradle命令行启动)的技巧。
  3. 用法

    解决方案正如我所希望的那样工作。每次修改此库中的某些代码时,我都会在命令行执行以下任务(除了构建解析器jar之外,还会执行其他一些代码和资源生成步骤):

    ./gradlew generateEclipse
    

    然后在Eclipse中按下" Gradle - >键盘快捷键。刷新Gradle项目",Build。

    恢复和谐。 : - )

    • 导航到parser的(预建)来源。
    • 如果我需要编辑源代码,我可以打开parser项目并进行编辑。 Scala-IDE仍然可以做得很好。
    • 当我完成后,我执行命令,关闭项目,我的Java工具很高兴。