Spring WS、JAXB/XSD 的 Maven 项目,用于创建服务器 WAR/EAR 和客户端 JAR,还可以从 XSD 自动生成类
可能很难准确解释我想要什么,所以请让我一步一步地做。
我们公司有一个长期存在的 Java 项目,它使用 Spring WS、XSD 文件来生成 WSDL 以及来自 WSDL 的那些 bean。项目使用 ANT 和各种目标进行编译/构建(一个目标用于从 XSD 生成类,另一个目标用于生成客户端 JAR,另一个目标用于生成服务器 WAR/EAR)。该项目用于运行 SOAP 服务器,也用于生成客户端 JAR。但不再有单一的代码源,而且预生成的客户端 JAR 数量也不断增加。我需要使用 Maven 来清理这个烂摊子。
我创建了模块化 Maven 项目,但基本上唯一真正的子项目是包含所有自定义代码、所有 XSD 等的项目(另一个子项目只是从第一个项目生成的 WAR 中打包 EAR)。由于该项目使用 Spring WS,因此最终的 WSDL 文件是在服务器上运行时动态生成的。
到目前为止,我所做的是执行以下操作:
- 手动从 XSD 生成类,将这些类添加到 /src/main/java 以便永久存储它们,让 Maven 生成服务端架构的其余部分(WAR/EAR) 。
- 分别使用从运行服务器导入的 WSDL 文件通过使用 eclipse WTP 插件生成客户端 JAR 文件(创建新项目,将 WSDL 放入其中,使用 WTP 插件生成文件,然后将项目导出到最终的 JAR 文件),然后将此 JAR 分发到感兴趣的各方。
这是可行的,但是正如您所看到的代码维护过程有问题(预生成的类包含在主源中),生成客户端的过程最多与主项目分离。所以这是一个我希望能够清理的烂摊子。
我希望能够做的是这样的:
- 创建托管 XSD 文件的 Maven 项目,
- 使用它来生成类,客户端 JAR
- 从服务器端项目引用该项目,以便服务器端代码可以引用生成的
- 类服务器端项目是使用 Spring WS 并且能够生成 EAR 文件的项目
我面临的问题很简单:动态生成 WSDL 的 XSD 文件应该真正驻留在该服务器项目中,而不是客户端项目中。这些文件需要位于 /src/main/resources 中,以便将它们移动到构建的 WAR/EAR 文件的类路径中。我可以使用 XSD 的两个不同副本 - 一个在客户端项目上,另一个在服务器端项目上,但这听起来不对。
所以我的主要问题实际上是 - 如何使用 Maven 处理这个项目架构,以便我只使用任何源文件(XSD、Java 等)的单个实例,并且我能够方便地从 XSD 生成类、构建客户端 JAR 和服务器战争/耳朵。我可以使用两个或多个单独的构建命令 - 一个生成 JAR,另一个从正确的项目源生成 EAR。
哦,顺便说一句 - 重构 XSD 文件是不可能的 - 它们是给我们的,必须按原样使用。
谢谢, 尼古拉
It may be difficult to explain exactly what I want, so please let me do step-by-step.
Our company has long-lived Java project that uses Spring WS, XSD files to generate WSDL and those beans from WSDL. Project is compiled/built using ANT with various targets (one target to generate classes from XSD, another to generate client JAR, another to generate Server WAR/EAR). This project used to run SOAP server and also used to generate client side JAR. But there is no single source of code anymore and number of pre-generated client JARs are flying around. I need to clean this mess using Maven.
I created modular Maven project, but basically the only real child project is one that contains all the custom code, all XSDs, etc (another child project simply packages EAR from the WAR generated by first project). Since this project uses Spring WS the final WSDL file is generated dynamically when run on server.
What I have managed so far is to do following:
- generate classes from XSD manually, add those classes to the /src/main/java so that they are stored permanently, have Maven to generate the rest of Service side architecture (WAR/EAR).
- separately using the WSDL file imported from running server generate Client JAR file by using eclipse WTP plugin (create new project, drop the WSDL into it, use WTP plugin to generate files, then export project into final JAR file) and then distribute this JAR to interested parties.
This works, but as you see the process of code maintenance has problem (pregenerated classes are included into the main source), the process of generating client is at best detached from the main project. So it is a mess I would like to be able to clean up.
What I would like to be able to do is something like this:
- create Maven project that hosts XSD files
- use it to generate classes and Client JAR
- refer to this project from Server side project so that the generated classes can be referenced by server side code
- the server side project is the one that would use Spring WS and that would be able to generate EAR file
The issue I am facing is simple: the XSD files to generate WSDL dynamically should really reside in that server project, not in client project. These files need to be in /src/main/resources so they are moved to class path of built WAR/EAR file. I could use two different copies of XSD - one on client side project another on server side project, but it sounds wrong.
So my main question really is - how do I approach this project architecture using Maven so that I only use single instance of any source file (XSD, Java, etc) and I am able to conveniently generate classes from XSD, build Client JAR and server WAR/EAR. I am OK with two or more separate build commands - one generates JAR, another generate EAR from proper project sources.
Oh by the way - refactoring the XSD files is out of question - they are given to us and must be used AS IS.
Thanks,
Nikolay
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
仅针对 XSD 使用单独的项目,并仅使用从 XSD 生成的类构建另一个 JAR。您最终拥有 3 个项目:
,其中客户端 JAR 和服务器项目依赖于 XSD 架构项目。
您可以通过使用包含所有这些项目的父项目一次性构建整个项目 子模块。
如果您担心您的客户端 JAR 现在实际上是两个 JAR(可能还有更多依赖项),您可以使用 shade 插件,用于将 XSD 架构项目 JAR 的内容捆绑到客户端 JAR 中。
创建更多项目/模块几乎总是比复制代码更好。
编辑:要从 WSDL 和 XML 模式生成类,您可以使用 Maven JAX- WS 插件(wsimport 目标)和/或 Maven JAXB插件。
Use a separate project for the just XSDs and build another JAR with just the classes generated from the XSDs. You end up having 3 projects:
where the client JAR and server projects have a dependency on the XSD schema project.
You can build the whole thing in one go by using a parent project with all these projects as child modules.
If you are concerned that your client JAR is now actually two JARs (plus possibly more dependencies) you can use the shade plugin to bundle the contents of the XSD schema project's JAR in your client JAR.
Creating more projects/modules is almost always better than duplicating code.
Edit: To generate classes from WSDLs and XML Schema, you can use the Maven JAX-WS plugin (wsimport goal) and/or the Maven JAXB plugin.
我们从 XSD 生成了大量代码。因为我们不想要重复的代码,所以我们使用 XML 目录和自定义模式解析器,它可以解析类路径中的模式;我相当确定 apache 有一个模式解析器也可以做到这一点 - 我记得在我们编写我们的模式解析器之后找到了它。通过这种方式,一个模块可以通过将另一个模块的工件声明为依赖项来引用该架构。
We generate quite a bit of code from XSDs. Because we didn't want duplicate code, we use XML catalogs and a custom schema resolver which can resolve schemas from the classpath; I'm fairly sure apache has a schema resolver that will do this too - I remember finding it after we wrote ours. In this way one module can reference the schema from another module's artifact by declaring it as a dependency.