简体   繁体   English

如何在Eclipse PDE中表达项目间依赖项

[英]How to express inter project dependencies in Eclipse PDE

I am looking for the best practice of handling inter project dependencies between mixed project types where some of the projects are eclipse plug-in/OSGI bundle projects (an RCP application) and others are just plain old java projects (web services modules). 我正在寻找处理混合项目类型之间的项目间依赖关系的最佳实践,其中一些项目是eclipse插件/ OSGI包项目(RCP应用程序),而其他项目只是普通的旧Java项目(Web服务模块)。 Few of the eclipse plug-ins have dependencies on Java projects. 很少有eclipse插件依赖于Java项目。

My problem is that at least as far as I've looked, there is no way of cleanly expressing such a dependency in Eclipse PDE environment. 我的问题是,至少就我看来,没有办法在Eclipse PDE环境中干净地表达这种依赖。 I can have plug-in projects depend on other plug-in projects (via Import-Package or Require-Bundle manifest headers), but not of the plain java projects. 我可以让插件项目依赖于其他插件项目(通过Import-PackageRequire-Bundle清单头文件),而不是普通java项目。

I seem to be able to have project declare a dependency on a jar from another project in a workspace, but these jar files do not get picked up by neither export nor launch configuration (although, java code editing sees the libraries just fine). 我似乎能够让项目从工作空间中的另一个项目声明对jar的依赖,但这些jar文件既不会被导出也不会被启动配置(虽然,java代码编辑看到库很好)。

The "Java projects" are used for building services to be deployed on an J2EE container (JBoss 4.2.2 for the moment) and produce in some cases multiple jar's - one for deploying to the JBoss ear and another for use by client code (an RCP application). “Java项目”用于构建部署在J2EE容器(目前为JBoss 4.2.2)上的服务,并在某些情况下生成多个jar - 一个用于部署到JBoss耳朵,另一个用于客户端代码(一个用于客户端代码) RCP应用程序)。

The way we've "solved" this problem for now is that we have 2 more external tools launcher configurations - one for building all the jar's and another for copying these jar's to the plug-in projects. 我们现在“解决”这个问题的方式是我们还有两个外部工具启动器配置 - 一个用于构建所有jar,另一个用于将这些jar复制到插件项目中。 This works (sort of), but the "whole build" and "copy jars" targets incur quite a large build step, bypassing the whole eclipse incremental build feature and by copying the jars instead of just referencing the projects I am decoupling the dependency information and requesting quite a massive workspace refresh that eats up the development time like it was candy. 这样做(有点),但是“整个构建”和“复制罐子”目标会产生相当大的构建步骤,绕过整个eclipse增量构建功能并通过复制jar而不是仅仅引用项目我将依赖关系信息解耦并请求相当大的工作空间刷新,这就像糖果一样耗尽了开发时间。

What I would like to have is a much more "natural" workspace setup that would manage dependencies between projects and request incremental rebuilds only as they are needed, be able to use client code from service libraries in an RCP application plug-ins and be able to launch the RCP application with all the necessary classes where they are needed. 我想要的是一个更加“自然”的工作空间设置,它可以管理项目之间的依赖关系并仅在需要时请求增量重建,能够使用RCP应用程序插件中的服务库中的客户端代码并且能够启动RCP应用程序,其中包含所需的所有必需类。

So can I have my cake and eat it too ;) 那么我可以吃蛋糕吗?)

NOTE 注意

To be clear, this is not so much about dependency management and module management at the moment as it is about Eclipse PDE configuration. 需要说明的是,目前依赖管理和模块管理与Eclipse PDE配置有关。

I am well aware of products like [Maven], [Ivy] and [Buckminster] and they solve a quite different problem (once I've solved the workspace configuration issue, these products can actually come in handy for materializing the workspace and building the product) 我很清楚像[Maven],[Ivy]和[Buckminster]这样的产品,他们解决了一个完全不同的问题(一旦我解决了工作区配置问题,这些产品实际上可以派上用场实现工作空间并构建产品)

Eclipse projects depend on each other by virtue of the checkbox in the project's properties (dependent projects?) which is how Eclipse decides which to build. Eclipse项目依赖于项目属性(依赖项目?)中的复选框,这就是Eclipse决定构建哪个项目的方式。 You can set this yourself, but it's usually set when you change your Java build path. 您可以自己设置,但通常在更改Java构建路径时设置。 It stores the data in the .project file IIRC so once you've gone through the GUI and seen what changes, you can be more flexible in how you apply the others. 它将数据存储在.project文件IIRC中,因此一旦您浏览了GUI并看到了哪些更改,您就可以更灵活地应用其他文件。

However, it sounds like you want to mix and match Jars and Bundles. 但是,听起来你想要混合搭配Jars和Bundles。 The easy way to do that is just treat all projects as Java projects. 简单的方法是将所有项目视为Java项目。 In the PDE project, you can actually go in and tweak the Java build path; 在PDE项目中,您实际上可以进入并调整Java构建路径; it'll complain and say that it isn't the right way to do it, but it will allow you to have a PDE project depend on a Java project without all that fluffy JARing up. 它会抱怨并说它不是正确的方法,但它会让你有一个PDE项目依赖于Java项目而没有那么蓬松的JARing。 Having said that, it wouldn't surprise me if there were runtime problems with this approach - the PDE runtime is likely to not see it that way. 话虽如此,如果这种方法存在运行时问题,我也不会感到惊讶 - PDE运行时可能不会这样看。

The other approach is to make your JARs themselves PDE/OSGi bundles. 另一种方法是让你的JAR自己成为PDE / OSGi包。 After all, an OSGi bundle is nothing more than a JAR with a bit of extra cruft in the Manifest, and it will let you develop and assemble your projects trivially using automatic dependency management. 毕竟,一个OSGi包只不过是一个JAR,它在Manifest中有一些额外的功能,它可以让你使用自动依赖管理轻松地开发和组装你的项目。 That's probably the easiest one to go for, even if you don't really need the manifest to be present in your bundles. 这可能是最容易实现的,即使你真的不需要清单出现在你的捆绑包中。 But doing this will mean your PDE app can be shipped with a more modular approach instead of embedding the libraries in each plugin as necessary. 但这样做意味着您的PDE应用程序可以采用更模块化的方法,而不是根据需要在每个插件中嵌入库。

So, PDE can generate OSGi bundles, and that's just another name for JAR + Manifest stuff. 因此,PDE可以生成OSGi包,这只是JAR + Manifest的另一个名称。 You can use a JAR in exactly the same way in other environments (eg for your EAR or other client uses) and you can take advantage of the OSGi layer in your app. 您可以在其他环境中以完全相同的方式使用JAR(例如,对于您的EAR或其他客户端使用),您可以利用应用程序中的OSGi层。 There's really no reason not to do this given the type of hybrid bundle that you're talking about. 考虑到你所谈论的混合束的类型,没有理由不这样做。

I never did it so this is a theoretical approach. 我从来没有这样做过,所以这是一种理论方法。 But I'd try a dependency management system like ivy or maven2. 但我会尝试像ivy或maven2这样的依赖管理系统。

Since maven2 does much more, then just dependency management, I'd recommend ivy in this case. 由于maven2做得更多,然后只是依赖管理,我建议在这种情况下使用常春藤。

Our solution uses an Ant builder to copy the "classes" directories of the plain Java projects directly into the top directory of the plugin project. 我们的解决方案使用Ant构建器将普通Java项目的“classes”目录直接复制到插件项目的顶层目录中。 We skip the JAR building step to save time, and it works pretty well. 我们跳过JAR构建步骤以节省时间,并且它运行良好。 If the plugin project depends on external JARs that're already built, we copy those in too. 如果插件项目依赖于已经构建的外部JAR,我们也会复制它们。

Here's exactly how to set it up in Eclipse 3.5 (sorry for the odd formatting, but that's the only way I could find to preserve indentation): 这里是如何在Eclipse 3.5中设置它(抱歉奇怪的格式,但这是我能找到保留缩进的唯一方法):

 Create empty "classes" dir in plugin project Select plugin project, hit F5 to refresh resources Create new Ant build file in plugin project to copy dependencies (ours is shown below) Right-click plugin project, select Properties Select Builders Click "New..." (brings up Edit Configuration dialog) Select Ant Builder and click "OK" Name your builder (ours is called "PluginProject externals") Browse workspace for Buildfile (ours is ${workspace_loc:/PluginProject/copyDependencies.xml}) click Refresh tab check "Refresh resources upon completion", click "Specific resources" click "Specify Resources...", check box for the classes dir, click "Finish" Click "OK" (closes Edit Configuration dialog) Click "Up" to move "PluginProject externals" to top of builder list Click "OK" (closes Properties dialog) Open your plugin project's MANIFEST.MF Click "Runtime" tab Click "Add..." under "Classpath", select your the "classes" dir and JARs and click "OK" 

The manual creation of the empty "classes" directory in the plugin project is so you can tell your new builder to refresh that resource (which doesn't exist yet before the new builder is run). 在插件项目中手动创建空的“classes”目录是为了让您可以告诉新构建器刷新该资源(在运行新构建器之前尚不存在)。 Here's what's in our copyDependencies.xml file: 这是我们的copyDependencies.xml文件中的内容:

<project name="Copy dependencies" default="copyDependencies" basedir=".">
  <!--
    This copying is needed because it appears that Eclipse plugins can't
    depend directly on external Eclipse projects.
  -->
  <description>
    Copies external dependency class andd JAR files into this plugin's directory.
  </description>

  <target name="copyDependencies">
    <copy file="../External/JDOM/jdom-1.0/build/jdom.jar" todir="." preservelastmodified="true"/>
    <copy file="../External/Xalan/xalan-j_2_6_0/bin/xalan.jar" todir="." preservelastmodified="true"/>
    <copy file="../External/Xalan/xalan-j_2_6_0/bin/xercesImpl.jar" todir="." preservelastmodified="true"/>
    <copy file="../External/Xalan/xalan-j_2_6_0/bin/xml-apis.jar" todir="." preservelastmodified="true"/>
    <copy todir="./classes/com/arm" preservelastmodified="true">
      <fileset dir="../Utilities/src/com/arm" excludes="**/*.java"/>
    </copy>
  </target>
  <target name="clean" description="Deletes local copies of external classes and JARs.">
    <delete file="jdom.jar" quiet="true"/>
    <delete file="xalan.jar" quiet="true"/>
    <delete file="xercesImpl.jar" quiet="true"/>
    <delete file="xml-apis.jar" quiet="true"/>
    <delete dir="./classes/com/arm/utilities" quiet="true"/>
  </target>
</project>

The only downside to this method seems to be that Eclipse isn't 100% perfect about invoking the external builder when it needs to be invoked, so occasionally you have to do a "Project > Clean..." in Eclipse to force it along. 这个方法唯一的缺点似乎是Eclipse在调用外部构建器时不是100%完美,所以偶尔你必须在Eclipse中执行“Project> Clean ...”来强制它。

You have my sympathies. 你有我的同情心。 I too have battled with this issue and the Wall-of-Silence from the Eclipse devs on such a simple, obvious question: how to declare a dependency from a plugin to a normal Java project (such that it works at runtime)? 我也与这个问题作斗争,Eclipse开发的Wall-of-Silence开发了一个如此简单明了的问题:如何从插件声明一个依赖项到普通的Java项目(这样它在运行时工作)?

I dont think they support it. 我不认为他们支持它。 The only way Ive got around the problem is to create folders inside my plugin projects that are actually links to the bin/ folders of the java projects, and then include these folders into the plugin. 解决问题的唯一方法是在我的插件项目中创建文件夹,这些文件夹实际上是指向java项目的bin /文件夹的链接,然后将这些文件夹包含在插件中。 That at least works, but its brittle due to the absolute filesystem paths required. 这至少有效,但由于需要绝对的文件系统路径,它很脆弱。

maybe you can use "project properties" -> "deployment assembly" on Eclipse, and add other projects to your main project. 也许你可以在Eclipse上使用“项目属性” - >“部署程序集”,并将其他项目添加到主项目中。 The other projects are seeing like "jars" that automatically are added to your deployment file (war, ear or whatever). 其他项目看起来像“罐子”,自动添加到您的部署文件(战争,耳朵或其他)。 Maybe this can be works. 也许这可行。 At least it works for me. 至少它对我有用。 Good luck !! 祝好运 !!

Ariesandes. Ariesandes。

There is a "Link source" option in Build path properties that allows you to define additional source folders for a project. Build path属性中有一个“链接源”选项,允许您为项目定义其他源文件夹。 You can selected the "src" folder of another workspace project and rename it to "src2" or whatever you want. 您可以选择另一个工作区项目的“src”文件夹,并将其重命名为“src2”或任何您想要的。 This way classes are compiled and deployed into the plug-in project output folder and can be loaded at runtime. 这样,类被编译并部署到插件项目输出文件夹中,并且可以在运行时加载。

With a complex set of build dependencies, I've found Maven2 and Hudson (for CI) to be a pretty nice combination. 通过一组复杂的构建依赖关系,我发现Maven2和Hudson(用于CI)是一个非常好的组合。 It took a while to set up the infrastructure and get my head around configuration, but after that, it just worked. 设置基础架构需要一段时间才能完成配置,但在此之后,它才起作用。

Of course, you are dependent then on Maven2 (or Hudson) support for your build mechanism. 当然,您依赖于Maven2(或Hudson)对构建机制的支持。 I'm not sure how well Eclipse Headless builds are supported. 我不确定Eclipse Headless构建的支持程度如何。 But if the only reason you're using Eclipse headless is to allow the dependencies to be expressed in a single place, do yourself a favour and switch. 但是,如果您使用Eclipse无头的唯一原因是允许依赖关系在一个地方表达,请自己帮忙并切换。

I am having the exact same problems. 我遇到了完全相同的问题。 We have a set of multiple normal java projects that can be built by Maven and should (currently) all share the same classpath to work properly. 我们有一组可以由Maven构建的多个普通java项目,并且(当前)应该共享相同的类路径以正常工作。 These projects can be used to start a server in a non-OSGi environment. 这些项目可用于在非OSGi环境中启动服务器。 Then we also have an eclipse RCP client which uses these projects as one bundle. 然后我们还有一个eclipse RCP客户端,它将这些项目作为一个捆绑包使用。 I am perfectly able to build this one-big-bundle with Maven using the Apache Felix Maven Bundle Plugin and everything works fine. 我完全能够使用Apache Felix Maven Bundle Plugin使用Maven构建这个大包,一切正常。 But whenever I change one class in the normal project I have to rebuild the entire bundle. 但每当我在正常项目中更改一个类时,我必须重建整个包。 Incremental build and resource linking does not work. 增量构建和资源链接不起作用。

I tried the "solution" with linking binaries/source directories from these projects into the Manifest classpath of the one-big-bundle and it seems to work but it would be a real maintenance nightmare because I even have to link some individual files. 我尝试了将这些项目中的二进制文件/源目录链接到一个大包的Manifest类路径中的“解决方案”,它似乎可以工作,但这将是一个真正的维护噩梦,因为我甚至必须链接一些单独的文件。

So ironically BECAUSE of the use of OSGi in the client I am actually thinking of collapsing our nice and modular structure with Maven modules into subpackages of only one plugin project. 具有讽刺意味的是,由于OSGi在客户端的使用,我实际上正在考虑将我们漂亮的模块化结构与Maven模块合并到一个插件项目的子包中。 This is a better alternative than having extremely slow development. 这是一个比开发速度极慢的更好的选择。

The other and better alternative (according to the OSGi guys) which I will investigate first is to make all my Maven modules into OSGi bundles. 我将首先调查的另一个更好的替代方案(根据OSGi人员)是将我的所有Maven模块都变成OSGi包。 But this may be a real PITA because I depend on classpath scanning and combining multiple configuration files from several bundles (with sometimes the same name) to form one configuration. 但这可能是一个真正的PITA,因为我依赖于类路径扫描并组合来自多个包(有时是同一个名称)的多个配置文件来形成一个配置。

(Specifically we use the Spring framework and we merge multiple persistence.xml files into one persistence context. We also merge several spring XML context files from different modules (all providing a different ASPECT) that should together form one Spring context to be used by Spring-DM.) (具体来说,我们使用Spring框架,并将多个persistence.xml文件合并到一个持久化上下文中。我们还合并了来自不同模块的几个spring XML上下文文件(都提供了不同的ASPECT),这些文件应该共同构成Spring要使用的一个Spring上下文-DM)。

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

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