在两个或多个项目之间共享公共代码(例如域类)的最佳方法是什么?

时间:2021-04-20 20:58:36

We are developing a Web application consisting of two Eclipse projects. One project is an HTTP-based RESTful Web service; the other project is a Web site. Both will be deployed as WARs. Initially, both will be deployed under the same application server instance, but eventually they'll be on separate boxes.

我们正在开发一个由两个Eclipse项目组成的Web应用程序。一个项目是基于HTTP的RESTful Web服务;另一个项目是一个网站。两者都将部署为WAR。最初,两者都将部署在同一个应用服务器实例下,但最终它们将位于不同的盒子上。

The Web site app consumes the RESTful WS app. Obviously, there will be code--specifically, domain classes--that are common to both projects. For instance, there might be a resource located at <app>/users which exposes CRUD operations on User objects; to update a user, the Web site app would POST an XML-marshalled User object to <app>/users. Doing a GET to <app>/users/1 would return an XML-marshalled User object.

该网站应用程序使用RESTful WS应用程序。显然,两个项目都会有代码 - 特别是域类 - 。例如,可能存在位于 / users的资源,该资源在User对象上公开CRUD操作;要更新用户,网站应用程序会将XML编组的用户对象POST到 / users。对 / users / 1执行GET将返回一个XML编组的User对象。

Obviously, having a User class in both projects would be pretty stupid for a variety of reasons. So I'm wondering what is the best way to go about this? Putting the common code in a JAR that's shared between the two projects is what I have done in the past, but is there a better or easier way?

显然,由于各种原因,在两个项目中都有一个User类非常愚蠢。所以我想知道最好的方法是什么?将公共代码放在两个项目之间共享的JAR中是我过去所做的,但有更好或更简单的方法吗?

Edit: Removed RESTful references. Semantics aside, what is the right way to share common code between two Eclipse projects?

编辑:删除RESTful引用。除了语义之外,在两个Eclipse项目之间共享公共代码的正确方法是什么?

7 个解决方案

#1


12  

Separation of concerns

关注点分离

Actually creating a third project and adding project dependencies is the best way, because Separation of concerns isn't only a principle for classes but also for software modules. It creates some advantages:

实际上创建第三个项目并添加项目依赖项是最好的方法,因为关注点的分离不仅是类的原则,也是软件模块的原则。它创造了一些优势:

  • Less code to read to learn the ropes of one project.
  • 阅读更少的代码来学习一个项目的绳索。
  • Better dependency control, because you could leave out some inter-project dependencies, so that using classes of the wrong module isn't possible.
  • 更好的依赖控制,因为你可以省略一些项目间的依赖关系,因此使用错误模块的类是不可能的。
  • Duplicating code is awful.
  • 复制代码很糟糕。

Project Structure

项目结构

Make sure you're not creating one big "utility" project, but rather domain-specific projects, like user management or addressbook.

确保您没有创建一个大的“实用程序”项目,而是创建特定于域的项目,如用户管理或地址簿。

In your case, it could be

在你的情况下,它可能是

  • user-api contains User transfer object
  • user-api包含用户传输对象
  • user-service provides CRUD operations
  • user-service提供CRUD操作
  • webapp (or user-client) calls user-service.
  • webapp(或用户 - 客户端)调用用户服务。

Other Build Systems

其他构建系统

When moving to continuous integration you'll need to use a better build system than Eclipse, but the principles are the same. You'll create small modules with minimal dependencies.

当转向持续集成时,您需要使用比Eclipse更好的构建系统,但原则是相同的。您将创建具有最小依赖性的小模块。

The most popular Build Systems for Java projects are Maven, Ant and Gradle. Each has its own way to define module dependencies.

最受欢迎的Java系统构建项目是Maven,Ant和Gradle。每种方法都有自己的方式来定义模块依赖性。

Project references in Eclipse

Eclipse中的项目引用

To tell Eclipse about project dependencies, right click on the project, open the properties and switch to the project references. Here you could mark dependencies, so that code changes will take effect immediately without copying a JAR file manually.

要告诉Eclipse有关项目依赖性的信息,请右键单击该项目,打开属性并切换到项目引用。在这里,您可以标记依赖项,以便代码更改将立即生效,而无需手动复制JAR文件。

在两个或多个项目之间共享公共代码(例如域类)的最佳方法是什么?

#2


7  

Imho, this depends on your build system, not your IDE.

Imho,这取决于您的构建系统,而不是您的IDE。

So, if you

所以,如果你

  • use plain Eclipse to build and like to keep things simple, just add a third project and add a dependecy.
  • 使用纯Eclipse构建并希望保持简单,只需添加第三个项目并添加依赖项。
  • use osgi, you'd properly already have created a new osgi project.
  • 使用osgi,你已经正确地创建了一个新的osgi项目。
  • use a build tool, like maven or gradle, then setup a multi-project build.
  • 使用构建工具,如maven或gradle,然后设置多项目构建。

#3


5  

Usually you create a third project (e.g. core or shared) which contains the shared code. Just depend on it from both your projects.

通常,您创建包含共享代码的第三个项目(例如核心或共享)。只需从你的项目中依赖它。

#4


1  

You need to create another project (i.e. shared). All of my SERVER-CLIENT app i do like that.

您需要创建另一个项目(即共享)。我所有的SERVER-CLIENT应用程序都是这样的。

在两个或多个项目之间共享公共代码(例如域类)的最佳方法是什么?

Basicaly, shared module has the EJB interfaces that are used by client and implemented by ejbModule

Basicaly,共享模块具有客户端使用并由ejbModule实现的EJB接口

#5


1  

How do you use third party jars? Think about your common code to be third party jar and apply the same rule to your projects. You can use dependency management tool like maven in order to keep versioning in order.

你如何使用第三方罐子?将您的公共代码视为第三方jar并将相同的规则应用于您的项目。您可以使用像maven这样的依赖关系管理工具,以便按顺序保持版本控制。

If you want to upgrade to an Application Server where you can deploy EARs you can put the common code in a jar which is a dependency of your EAR... so other WAR projects in your EARs can use the common code.

如果要升级到可以部署EAR的Application Server,可以将公共代码放在jar中,这是EAR的依赖...因此,EAR中的其他WAR项目可以使用公共代码。

You can also give a try to OSGI.

您也可以尝试OSGI。

#6


0  

If you are sharing domain classes between a client and server in a RESTful system you are defeating the point of REST. The REST constraints are designed to allow a client and server system to independently evolve by ensuring that the only coupling between the two systems is confined to media types and link relations.

如果您在RESTful系统*享客户端和服务器之间的域类,那么您就无法实现REST。 REST约束旨在通过确保两个系统之间的唯一耦合仅限于媒体类型和链接关系,允许客户端和服务器系统独立发展。

If you need to share domain objects, forget about REST, it is going to me more trouble than it is worth.

如果你需要共享域对象,忘记REST,它会给我带来更多麻烦而不是值得。

#7


0  

there are several possible ways to do this, and depending on your specific situation and requirements, some might be better than other.

有几种可能的方法可以做到这一点,根据您的具体情况和要求,有些可能比其他方法更好。

in all cases, i would strongly recommend a system that understands version numbers.

在所有情况下,我强烈推荐一个了解版本号的系统。

a classic way to do this would be to use maven. also, it is very well integrated in eclipse and you can structure your modules as part of one parent project, such as:

一个经典的方法是使用maven。此外,它非常好地集成在eclipse中,您可以将模块构建为一个父项目的一部分,例如:

project-parent
    project-website1
    project-website2
    project-controllers
    project-model
    [...]

internally, these modules can then depend on each other. you can go as far as separating interfaces from the implementation:

在内部,这些模块可以相互依赖。你可以将接口与实现分开:

project-parent
    project-website1
    project-website2
    project-api
    project-api-impl
    [...]

and then depending on the api module most of the time. maven also has a few mechanisms for dealing with WAR files.

然后大部分时间取决于api模块。 maven还有一些处理WAR文件的机制。

this (single-project) approach is probably ideal for a very small development team. the main drawback is that it is quite unpractical to release things separately - a bugfix in the implementation that only affects website2 would also require a release of website1.

这种(单项目)方法可能是非常小的开发团队的理想选择。主要的缺点是单独发布内容是非常不切实际的 - 实现中只有影响website2的错误修正也需要发布website1。

also, the separation tends to be less clear in this, making it potentially too easy to move stuff into the shared modules that shouldn't really be there.

此外,这种分离往往不那么清晰,这使得将东西移动到不应该存在的共享模块中可能太容易了。

another pattern would be:

另一种模式是:

 project1-parent
      project1-webapp
      project1-specifics
      [...]

 project2-parent
      project2-webapp
      project2-specifics
      [...]

 common-parent
      common-api
      common-impl
      common-model
      [...]

this makes the separation a bit clearer, and you can release things separately. also (although this is probably not recommended under normal circumstances), project1-webapp could depend on an older or newer version of the common module than project2-webapp. maven can be found here:

这使分离更清晰,您可以单独发布。另外(虽然在正常情况下可能不建议这样做),project1-webapp可能依赖于比project2-webapp更旧或更新版本的通用模块。 maven可以在这里找到:

https://maven.apache.org/

another toolset that might help you deal with versioning is:

另一个可以帮助您处理版本控制的工具集是:

https://gradle.org/

to make the most of these, you might also want to look into using git with gitflow:

为了充分利用这些,您可能还需要考虑使用git和gitflow:

http://git-scm.com/
https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow/

and understand how to use this to deal with versioning and releasing.

并了解如何使用它来处理版本控制和发布。

personally, i found it VERY confusing when i first started out - but it all makes a lot of sense now.

就个人而言,我刚开始时发现它非常混乱 - 但现在这一切都很有意义。

#1


12  

Separation of concerns

关注点分离

Actually creating a third project and adding project dependencies is the best way, because Separation of concerns isn't only a principle for classes but also for software modules. It creates some advantages:

实际上创建第三个项目并添加项目依赖项是最好的方法,因为关注点的分离不仅是类的原则,也是软件模块的原则。它创造了一些优势:

  • Less code to read to learn the ropes of one project.
  • 阅读更少的代码来学习一个项目的绳索。
  • Better dependency control, because you could leave out some inter-project dependencies, so that using classes of the wrong module isn't possible.
  • 更好的依赖控制,因为你可以省略一些项目间的依赖关系,因此使用错误模块的类是不可能的。
  • Duplicating code is awful.
  • 复制代码很糟糕。

Project Structure

项目结构

Make sure you're not creating one big "utility" project, but rather domain-specific projects, like user management or addressbook.

确保您没有创建一个大的“实用程序”项目,而是创建特定于域的项目,如用户管理或地址簿。

In your case, it could be

在你的情况下,它可能是

  • user-api contains User transfer object
  • user-api包含用户传输对象
  • user-service provides CRUD operations
  • user-service提供CRUD操作
  • webapp (or user-client) calls user-service.
  • webapp(或用户 - 客户端)调用用户服务。

Other Build Systems

其他构建系统

When moving to continuous integration you'll need to use a better build system than Eclipse, but the principles are the same. You'll create small modules with minimal dependencies.

当转向持续集成时,您需要使用比Eclipse更好的构建系统,但原则是相同的。您将创建具有最小依赖性的小模块。

The most popular Build Systems for Java projects are Maven, Ant and Gradle. Each has its own way to define module dependencies.

最受欢迎的Java系统构建项目是Maven,Ant和Gradle。每种方法都有自己的方式来定义模块依赖性。

Project references in Eclipse

Eclipse中的项目引用

To tell Eclipse about project dependencies, right click on the project, open the properties and switch to the project references. Here you could mark dependencies, so that code changes will take effect immediately without copying a JAR file manually.

要告诉Eclipse有关项目依赖性的信息,请右键单击该项目,打开属性并切换到项目引用。在这里,您可以标记依赖项,以便代码更改将立即生效,而无需手动复制JAR文件。

在两个或多个项目之间共享公共代码(例如域类)的最佳方法是什么?

#2


7  

Imho, this depends on your build system, not your IDE.

Imho,这取决于您的构建系统,而不是您的IDE。

So, if you

所以,如果你

  • use plain Eclipse to build and like to keep things simple, just add a third project and add a dependecy.
  • 使用纯Eclipse构建并希望保持简单,只需添加第三个项目并添加依赖项。
  • use osgi, you'd properly already have created a new osgi project.
  • 使用osgi,你已经正确地创建了一个新的osgi项目。
  • use a build tool, like maven or gradle, then setup a multi-project build.
  • 使用构建工具,如maven或gradle,然后设置多项目构建。

#3


5  

Usually you create a third project (e.g. core or shared) which contains the shared code. Just depend on it from both your projects.

通常,您创建包含共享代码的第三个项目(例如核心或共享)。只需从你的项目中依赖它。

#4


1  

You need to create another project (i.e. shared). All of my SERVER-CLIENT app i do like that.

您需要创建另一个项目(即共享)。我所有的SERVER-CLIENT应用程序都是这样的。

在两个或多个项目之间共享公共代码(例如域类)的最佳方法是什么?

Basicaly, shared module has the EJB interfaces that are used by client and implemented by ejbModule

Basicaly,共享模块具有客户端使用并由ejbModule实现的EJB接口

#5


1  

How do you use third party jars? Think about your common code to be third party jar and apply the same rule to your projects. You can use dependency management tool like maven in order to keep versioning in order.

你如何使用第三方罐子?将您的公共代码视为第三方jar并将相同的规则应用于您的项目。您可以使用像maven这样的依赖关系管理工具,以便按顺序保持版本控制。

If you want to upgrade to an Application Server where you can deploy EARs you can put the common code in a jar which is a dependency of your EAR... so other WAR projects in your EARs can use the common code.

如果要升级到可以部署EAR的Application Server,可以将公共代码放在jar中,这是EAR的依赖...因此,EAR中的其他WAR项目可以使用公共代码。

You can also give a try to OSGI.

您也可以尝试OSGI。

#6


0  

If you are sharing domain classes between a client and server in a RESTful system you are defeating the point of REST. The REST constraints are designed to allow a client and server system to independently evolve by ensuring that the only coupling between the two systems is confined to media types and link relations.

如果您在RESTful系统*享客户端和服务器之间的域类,那么您就无法实现REST。 REST约束旨在通过确保两个系统之间的唯一耦合仅限于媒体类型和链接关系,允许客户端和服务器系统独立发展。

If you need to share domain objects, forget about REST, it is going to me more trouble than it is worth.

如果你需要共享域对象,忘记REST,它会给我带来更多麻烦而不是值得。

#7


0  

there are several possible ways to do this, and depending on your specific situation and requirements, some might be better than other.

有几种可能的方法可以做到这一点,根据您的具体情况和要求,有些可能比其他方法更好。

in all cases, i would strongly recommend a system that understands version numbers.

在所有情况下,我强烈推荐一个了解版本号的系统。

a classic way to do this would be to use maven. also, it is very well integrated in eclipse and you can structure your modules as part of one parent project, such as:

一个经典的方法是使用maven。此外,它非常好地集成在eclipse中,您可以将模块构建为一个父项目的一部分,例如:

project-parent
    project-website1
    project-website2
    project-controllers
    project-model
    [...]

internally, these modules can then depend on each other. you can go as far as separating interfaces from the implementation:

在内部,这些模块可以相互依赖。你可以将接口与实现分开:

project-parent
    project-website1
    project-website2
    project-api
    project-api-impl
    [...]

and then depending on the api module most of the time. maven also has a few mechanisms for dealing with WAR files.

然后大部分时间取决于api模块。 maven还有一些处理WAR文件的机制。

this (single-project) approach is probably ideal for a very small development team. the main drawback is that it is quite unpractical to release things separately - a bugfix in the implementation that only affects website2 would also require a release of website1.

这种(单项目)方法可能是非常小的开发团队的理想选择。主要的缺点是单独发布内容是非常不切实际的 - 实现中只有影响website2的错误修正也需要发布website1。

also, the separation tends to be less clear in this, making it potentially too easy to move stuff into the shared modules that shouldn't really be there.

此外,这种分离往往不那么清晰,这使得将东西移动到不应该存在的共享模块中可能太容易了。

another pattern would be:

另一种模式是:

 project1-parent
      project1-webapp
      project1-specifics
      [...]

 project2-parent
      project2-webapp
      project2-specifics
      [...]

 common-parent
      common-api
      common-impl
      common-model
      [...]

this makes the separation a bit clearer, and you can release things separately. also (although this is probably not recommended under normal circumstances), project1-webapp could depend on an older or newer version of the common module than project2-webapp. maven can be found here:

这使分离更清晰,您可以单独发布。另外(虽然在正常情况下可能不建议这样做),project1-webapp可能依赖于比project2-webapp更旧或更新版本的通用模块。 maven可以在这里找到:

https://maven.apache.org/

another toolset that might help you deal with versioning is:

另一个可以帮助您处理版本控制的工具集是:

https://gradle.org/

to make the most of these, you might also want to look into using git with gitflow:

为了充分利用这些,您可能还需要考虑使用git和gitflow:

http://git-scm.com/
https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow/

and understand how to use this to deal with versioning and releasing.

并了解如何使用它来处理版本控制和发布。

personally, i found it VERY confusing when i first started out - but it all makes a lot of sense now.

就个人而言,我刚开始时发现它非常混乱 - 但现在这一切都很有意义。