首页 \ 问答 \ 如何通过gradle打包REST客户端代码以实现多项目使用(How to package REST Client code via gradle for multi-project usage)

如何通过gradle打包REST客户端代码以实现多项目使用(How to package REST Client code via gradle for multi-project usage)

背景:

在多项目(比如Alpha和Beta)Java / Spring4.x环境中,Project Alpha需要在Project Beta中使用REST端点。 项目Alpha和Beta非常相关,将始终一起发布。 但是,它们也需要分开,因为代码将被构建到不同的部分中,这些部分将在不同的物理机器上执行 - 因此首先是REST实现!

稍微侧重点:UI代码在其他项目中,通常是各种REST端点的使用者,因此不需要使用REST客户端的Java实现。 REST客户端通常是src / main / test,因此它们甚至不打包,通常它们仅为单元测试创​​建。

具体细节:

给定的API在Project Beta中通过Interface类定义:

// located in /src/main/java/com/mycompany/myservice/api
public interface MyServiceApi {
    String getDataMethod();
}

Java REST Client目前也在Project Beta中(需要上面的API):

// currently located in /src/main/client/com/mycompany/myservice/client
public class MyServiceRestClient implements MyServiceApi {
    . . . 
}

问题:

对不起,花了这么长时间才来到这里! 两个项目都在相同的settings.gradle文件中定义 - 它们是一起构建的。 每个项目也有自己的build.gradle文件。 问题是如何只打包客户端REST工件,然后如何在Project Alpha中引用它们? 理想情况下,答案既可以使用gradle命令行,也可以使用Eclipse。 显然,在Project Alpha的build.gradle中使用它:

dependencies {
    compile project('beta')
}

不起作用,因为它带来了所有的项目Beta。 通过将客户端Java代码放入src / main / client ,我一直假设Project Beta需要定义一个sourceSet来处理这段代码。 我如何把它打包成一个Jar(我知道如何做这个部分), 最重要的是 ,从Project Alpha中引用Jar在同一个单项多项目gradle构建中? 或者,有更好的方法可以完全采用不同的方法吗?


Background:

In a multi-project (say Alpha and Beta) Java/Spring4.x environment where Project Alpha needs to use a REST endpoint in Project Beta. Projects Alpha and Beta ARE very related and will always be released together. However, they also need to be separate as the code will be built into different pieces that will execute on different physical machines - hence the REST implementation in the first place!

Slight side-point: The UI code is in other projects and is usually the consumer of the various REST endpoints and thus does not need to consume Java implementations of a REST Client. The REST Clients are usually src/main/test so they are not even packaged, generally they are only created for Unit Tests.

Specifics:

The given API is defined in Project Beta via an Interface class:

// located in /src/main/java/com/mycompany/myservice/api
public interface MyServiceApi {
    String getDataMethod();
}

The Java REST Client is also currently in Project Beta (needs the API above):

// currently located in /src/main/client/com/mycompany/myservice/client
public class MyServiceRestClient implements MyServiceApi {
    . . . 
}

The Question:

Sorry it has taken so long to get here! Both projects are defined in the same settings.gradle file - they are built together. Each project also has its own build.gradle file. The question is how to package only the client REST artifacts and then how to refer to them in Project Alpha? Ideally, the answer will work both from the gradle command line as well as within Eclipse. Clearly, using this in Project Alpha's build.gradle:

dependencies {
    compile project('beta')
}

does not work as that brings in ALL of project Beta. By putting the client Java code into src/main/client, I have been assuming Project Beta will need to define a sourceSet to process this code. How do I take that, package it into a Jar (I know how to do this part), AND MOST IMPORTANTLY, reference that Jar from Project Alpha all in the same, single multi-project gradle build? Or is there a much better way to do that is a different approach entirely?


原文:https://stackoverflow.com/questions/26382845
更新时间:2021-08-10 10:08

最满意答案

但是,在执行可能并行进程的下一阶段之前,填充输入缓冲区的进程将始终完成

如果这是有保证的,那么从const对象的不同线程中进行多次读取就没有问题。

我没有官方标准所以以下是n4296

17.6.5.9避免数据竞争

3 C ++标准库函数不应直接或间接修改除当前线程以外的线程可访问的对象(1.10),除非通过函数的非const参数直接或间接访问对象,包括此参数。

4 [注意:例如,这意味着实现不能在没有同步的情况下将静态对象用于内部目的,因为即使在未在线程之间显式共享对象的程序中,它也可能导致数据竞争。 - 尾注]


这是Herb Sutter视频 ,我第一次了解了C ++ 11标准中const的含义。 (见7:00到10:30左右)


but the process that fills the input buffer will always be complete before the next stage of possibly parallel processes will execute

If this is guaranteed then there is not a problem having multiple reads from different threads for const objects.

I don't have the official standard so the following is from n4296:

17.6.5.9 Data race avoidance

3 A C++ standard library function shall not directly or indirectly modify objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function’s non-const arguments, including this.

4 [ Note: This means, for example, that implementations can’t use a static object for internal purposes without synchronization because it could cause a data race even in programs that do not explicitly share objects between threads. —end note ]


Here is the Herb Sutter video where I first learned about the meaning of const in the C++11 standard. (see around 7:00 to 10:30)

相关问答

更多
  • 您可以考虑使用内存映射文件进行并发读取访问。 它将避免将数据复制到每个进程地址空间的开销。 You may consider Memory-Mapped Files for concurrent read access. It will avoid overhead of copying data into every process address space.
  • 但是,在执行可能并行进程的下一阶段之前,填充输入缓冲区的进程将始终完成 如果这是有保证的,那么从const对象的不同线程中进行多次读取就没有问题。 我没有官方标准所以以下是n4296 : 17.6.5.9避免数据竞争 3 C ++标准库函数不应直接或间接修改除当前线程以外的线程可访问的对象(1.10),除非通过函数的非const参数直接或间接访问对象,包括此参数。 4 [注意:例如,这意味着实现不能在没有同步的情况下将静态对象用于内部目的,因为即使在未在线程之间显式共享对象的程序中,它也可能导致数据竞争。 ...
  • A类是线程安全的,因为它只使用const函数,可以假设它们不会改变外部可见状态。 虽然如果类也有mutable成员, const函数能够修改内部状态,但通常假设任何mutable成员都是同步的,因此对象的两个并发读者永远不会遇到竞争条件。 访问shared_ptr的内容是线程安全的,实际上甚至不需要互斥锁的额外同步。 从cppreference : 所有成员函数(包括复制构造函数和复制赋值)都可以由shared_ptr的不同实例上的多个线程调用,而无需额外的同步,即使这些实例是副本并共享同一对象的所有权。 ...
  • 这两个类一次允许多个读取器没有锁定,必须为多个编写器锁定。 不同的是,Hashtable允许一个作者与多个读者一起使用而不需要锁定,而这对于Dictionary来说是不安全的。 因此,对于Hashtable,只能写入锁定。 如果键和值都是引用类型(因此不需要装箱/拆箱),在具有许多读者和一个(或多个)写入器的场景中,Hashtable可能比Dictionary更快,因为读者不必等待锁定所有。 使用Dictionary,相同的场景需要使用ReaderWriterLock 。 Both classes allo ...
  • 旧的System.Collections.Hashtable对于多读者 - 单写者场景是安全的,也就是说,任何数量的线程都可以从Hashtable读取,但最多一个线程可以同时对其进行修改。 (当读者正在阅读时,作者线程可以安全地修改Hashtable)。 通用Dictionary对于这样的场景是不安全的 - 改用ConcurrentDictionary 。 请注意, System.Collections.Hashtable和ConcurrentDictionary使用完全不同的 ...
  • 从文件中读取数据时,限制因素将是硬盘的读取速度 - 而不是CPU。 如果按顺序访问文件,则从文件中读取数据的速度最快。 When reading data from a file your limiting factor will be the read speed of the harddisk - not the CPU. Reading data from a file is fastest if you access the file sequentially.
  • 如果确保所有写入都发生 ,则可以跳过对该映射的读取访问的同步- 在所有读取之前 。 它的含义在JLS 7章17.4.5中有所描述。 在实践中,您必须确保在任何其他将访问它的线程启动之前填充HashMap ,并且在此之后其内容不会被修改。 此解决方案的工作原因是Thread.start()调用强制进行同步,因此保证在该调用之前进行的所有更改在该调用后对旧线程和新线程均可见。 如果在调用之后修改对象,则此保证将丢失,并且需要同步访问。 You can skip synchronization for the r ...
  • 您的代码非常糟糕,您不必担心任何性能影响。 您的代码不是线程安全的。 永远不要在可变变量上同步 ! synchronized(accounts[from]){ accounts[from] -= amount; } 此代码执行以下操作: from没有任何同步的位置读取数组accounts的内容,因此可能读取一个绝望的过时值,或者只是由仍在其synchronized块内的线程写入的值 锁定它已读取的任何对象(请记住, 自动装箱创建的Integer对象的标识未指定[除了-128到+127范围]) 再次 ...
  • 成员函数是线程安全的 ,你的接口不是 。 在设计为线程安全的类中,您不能产生对您维护的对象的引用 ,就好像用户保持引用放置,她可以在其他操作到位时使用它。 成员函数在技术上是线程安全的。 对成员的引用基本上是它的地址,并且该地址不能更改。 无论其他线程正在做什么,引用将始终引用完全相同的对象。 但这通常不是你主要担心的问题。 真正关心的是用户可以通过函数的返回做什么,在这种情况下答案基本上没有 。 一旦用户获得引用,当与原始对象中的该成员的任何修改组合时,通过它的任何访问都将导致竞争条件。 提供引用后,您无 ...
  • 是的,这是非常安全的。 只要MySetting没有改变,这就是使用FormatDateTime和其他类似程序的方法。 从文档, System.SysUtils.TFormatSettings : TFormatSettings类型的变量定义了一个线程安全的上下文,格式化函数可以使用它来代替默认的全局上下文,这不是线程安全的。 注意您必须通过编程提供此线程安全上下文。 仅当您确保在执行期间未更改参数及其共享时,它才是线程安全的。 通常,我的序列化库使用共享的常量格式设置变量,该变量在所有语言环境中提供稳定的读 ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)