简体   繁体   English

Gradle + Eclipse:在新项目中使用现有项目中的类

[英]Gradle + Eclipse : use class from existing project in a new project

I know there are a lot of questions that seem similar. 我知道有很多问题看起来很相似。 I have also spent a few hours getting to grips with Gradle multiprojects. 我还花了几个小时来熟悉Gradle多项目。 But I still don't understand what the best course of action is here. 但是我仍然不知道最好的行动方案是什么。 Incidentally I am using Groovy as my coding language, but explanations referencing Java would be just as good. 顺便说一下,我使用Groovy作为我的编码语言,但是引用Java的解释也一样。

I have developed an Eclipse Gradle project, "ProjectA", which in particular has a class, IndexManager , which is responsible for creating and opening and querying Lucene indices. 我已经开发了一个Eclipse Gradle项目“ ProjectA”,该项目特别具有一个IndexManager类, IndexManager负责创建,打开和查询Lucene索引。

Now I am developing a new Eclipse Gradle project, "ProjectB", which would like to use the IndexManager class from ProjectA. 现在,我正在开发一个新的Eclipse Gradle项目“ ProjectB”,该项目将使用ProjectA中的IndexManager类。

This doesn't really mean that I would like both projects to be part of a multiproject. 这并不是说我希望两个项目都成为多项目的一部分。 I don't want to compile the latest version of ProjectA each time I compile ProjectB - instead I would like ProjectB to be dependent on a specific version of ProjectA's IndexManager . 我不想每次编译ProjectB时都编译最新版本的ProjectA-相反,我希望ProjectB 依赖于 ProjectA的IndexManager 的特定版本 With the option of upgrading to a new version at some future point. 可以选择将来某个时候升级到新版本。 Ie much as with the sorts of dependencies you get from Maven or JCenter... 就像从Maven或JCenter获得的各种依赖一样...

Both projects have the application plugin, so ProjectA produces an executable .jar file whose name incorporates the version. 这两个项目都有application插件,因此ProjectA生成一个可执行的.jar文件,其名称包含该版本。 But currently this contains only the .class files, the resource files, and a file called MANIFEST.MF containing the line "Manifest-Version: 1.0". 但是当前它仅包含.class文件,资源文件以及名为MANIFEST.MF的文件,其中包含“ Manifest-Version:1.0”行。 Obviously it doesn't contain any of the dependencies (eg Lucene jar files) needed by the .class files. 显然,它不包含.class文件所需的任何依赖项(例如Lucene jar文件)。

The application plugin also lets you produce a runnable distribution: this consists of an executable file (2 in fact, one for *nix/Cygwin, one for Windows), but also all the .jar dependencies needed to run it. application插件还允许您生成可运行的分发:它包含一个可执行文件(实际上是2个文件,一个用于* nix / Cygwin,一个用于Windows),还包括运行该文件所需的所有.jar依赖项。

Could someone explain how I might accomplish the task of packaging up this class, IndexManager (or alternatively all the classes in ProjectA possibly), and then including it in my dependencies clause of ProjectB's build.gradle... and then using it in a given file (Groovy or Java) of ProjectB? 有人可以解释我如何完成打包此类, IndexManager (或者可能的其他方式是ProjectA中的所有类),然后将其包含在ProjectB的build.gradle的dependencies项中,然后在给定的条件中使用的任务。文件(Groovy或Java)?

Or point to some tutorial about the best course of action? 还是指向一些有关最佳操作方法的教程?

One possible answer to this which I seem to have found, but find a bit unsatisfactory, appears to be to take the class which is to be used by multiple projects, here IndexManager , and put it in a Gradle project which is specifically designed to be a Groovy library. 我似乎已经找到了一个可能的答案,但发现有点不令人满意,似乎是将要由多个项目使用的类(这里为IndexManager )放在一个专门设计用于以下目的的Gradle项目中: Groovy库。 To this end, you can kick it off by creating the project directory and then: 为此,您可以通过创建项目目录,然后开始:

$ gradle init --type groovy-library

... possible to do from the Cygwin prompt, but not from within Eclipse as far as I know. ...可以从Cygwin提示符下执行,但据我所知,不是从Eclipse内执行。 So you then have to import it into Eclipse. 因此,您必须将其导入Eclipse。 build.gradle in this library project then has to include the dependencies needed by IndexManager , in this case: 然后,此库项目中的build.gradle必须包含IndexManager所需的依赖IndexManager ,在这种情况下:

compile 'org.apache.lucene:lucene-analyzers-common:6.+'
compile 'org.apache.lucene:lucene-queryparser:6.+'
compile 'org.apache.lucene:lucene-highlighter:6.+'
compile 'commons-io:commons-io:2.6'
compile 'org.apache.poi:poi-ooxml:4.0.0'
compile 'ch.qos.logback:logback-classic:1.2.1'

After this, I ran gradle jar to create the .jar which contains this IndexManager class, initially without any fancy stuff in the manifest (eg name, version). 之后,我运行gradle jar创建包含该IndexManager类的.jar,最初在清单中没有任何奇特的东西(例如名称,版本)。 And I put this .jar file in a dedicated local directory. 然后,我将该.jar文件放在专用的本地目录中。

Then I created another Gradle project to use this .jar file, the critical dependency here being 然后,我创建了另一个Gradle项目来使用此.jar文件,这里的关键依赖项是

compile files('D:/My Documents/software projects/misc/localJars/XGradleLibExp.jar' )

The file to use this class looks like this: 使用此类的文件如下所示:

package core
import XGradleLibExp.IndexManager

class Test {
    public static void main( args ) {
        println "hello xxx"
        Printer printer = new Printer()
        IndexManager im = new IndexManager(  printer )
        def result = im.makeIndexFromDbaseTable()
        println "call result $result"
    }
}

class Printer {
    def outPS = new PrintStream(System.out, true, 'UTF-8' )
}

... I had designed IndexManager to use an auxiliary class, which had a property outPS . ...我将IndexManager设计为使用辅助类,该辅助类的属性为outPS Groovy duck-typing means you just have to supply anything with such a property and hopefully things work. 时髦的鸭式打字意味着您只需要提供具有这种属性的任何东西,就可以希望一切正常。

The above arrangement didn't run: although you can do build and installdist without errors, the attempt to execute the distributed executable fails because the above 6 compile dependency lines are not present in build.gradle of the "consumer" project. 上面的安排没有运行:尽管您可以installdist进行buildinstalldist ,但是由于在“ consumer”项目的build.gradle中没有上述6个compile依赖项行,因此执行分布式可执行文件的尝试失败。 When you put them in this "consumer" Gradle project's build.gradle, it works. 当您将它们放在此“消费者” Gradle项目的build.gradle中时,它将起作用。

No doubt you can add the version to the generated .jar file, and thus keep older versions for use with "consumer" projects. 毫无疑问,您可以将版本添加到生成的.jar文件中,从而保留较旧的版本以用于“消费者”项目。 What I don't understand is how you might harness the mechanism which makes the downloading and use of the dependencies needed by the .jar as automatic as we are used to for things obtained from "real repositories". 我不了解的是,您如何利用这种机制来自动下载和使用.jar所需的依赖项,就像我们习惯于从“真实存储库”中获取内容一样。


PS in the course of my struggles today I seem to have found that Gradle's "maven-publish" plugin is not compatible with Gradle 5.+ (which I'm using). PS在今天的奋斗过程中,我似乎发现Gradle的“行家发布”插件与Gradle 5。+(我正在使用的)不兼容。 This may or may not be relevant: some people have talked of using a "local Maven repository". 这可能相关,也可能不相关:有些人谈论使用“本地Maven存储库”。 I have no idea whether this is the answer to my problem... Await input from an über-Gradle-geek... :) 我不知道这是否是我的问题的答案...等待über-Gradle-geek的输入... :)

You should be able to update the Eclipse model to reflect this project-to-project dependency. 您应该能够更新Eclipse模型以反映此项目之间的依赖关系。 It looks something like this (in ProjectB's build.gradle): 看起来像这样(在ProjectB的build.gradle中):

apply plugin: 'eclipse'

eclipse {
  classpath.file.whenMerged {
    entries << new org.gradle.plugins.ide.eclipse.model.ProjectDependency('/ProjectA')
  }
  project.file.whenMerged {
    // add a project reference, which should show up in /ProjectB/.project's <projects> element
  }
}

These changes may be to the running data model, so they may not actually alter the .classpath and .project files. 这些更改可能是针对正在运行的数据模型,因此它们实际上可能不会更改.classpath.project文件。 More info can be found here: https://docs.gradle.org/current/dsl/org.gradle.plugins.ide.eclipse.model.EclipseModel.html 可以在这里找到更多信息: https : //docs.gradle.org/current/dsl/org.gradle.plugins.ide.eclipse.model.EclipseModel.html

This issue is discussed here: http://gradle.1045684.n5.nabble.com/Gradle-s-Eclipse-DSL-and-resolving-dependencies-to-workspace-projects-td4856525.html and a bug was opened but never resolved here: https://issues.gradle.org/browse/GRADLE-1014 在此处讨论此问题: http : //gradle.1045684.n5.nabble.com/Gradle-s-Eclipse-DSL-and-resolving-dependencies-to-workspace-projects-td4856525.html,并且已打开错误但从未出现过在这里解决: https//issues.gradle.org/browse/GRADLE-1014

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM