简体   繁体   English

如何在我的jar中包含外部类

[英]How to include external classes in my jar

I have a problem with a service I am trying to write. 我要编写的服务有问题。 I am trying to create a service that runs in the background on a windows system but uses java. 我正在尝试创建在Windows系统上在后台运行但使用Java的服务。 I have seen several ways of doing this, but decided on one method that seemed to meet my requirements. 我已经看到了几种方法,但是选择了一种似乎可以满足我要求的方法。 The service will check a database for items it needs to work on. 该服务将检查数据库中需要处理的项目。 When it finds an item in the DB that it needs to do it will run some system commands to take care of them. 当它在数据库中找到需要执行的项目时,它将运行一些系统命令来处理它们。

I found a way to use the tomcat7.exe file to run a jar as a service and that worked pretty well for basic stuff. 我找到了一种使用tomcat7.exe文件将jar作为服务运行的方法,该方法对于基本内容非常有效。 Anything I write and compile into my jar file "myService.jar" we'll can call it goes well enough. 我编写并编译到jar文件“ myService.jar”中的任何内容,我们都可以称其运行良好。 The problem is that we already have several classes written for accessing the DB and running commands that are precompiled in a library of classes called BGLib-1.0.jar. 问题在于,我们已经编写了几个用于访问数据库和运行命令的类,这些类已预编译在名为BGLib-1.0.jar的类库中。

I have used this library in writing several jenkins plugins and had no problems calling functions from it. 我已经使用该库编写了几个jenkins插件,并且从中调用函数没有问题。 They all work fine when I create an hpi file and deploy it in Jenkins. 当我创建一个hpi文件并将其部署在Jenkins中时,它们都可以正常工作。 There the compiler (Eclipse using Maven) packages the BGLib jar in with the plugin jar and Jenkins figures out how to get them to see one another. 在那里,编译器(使用Maven的Eclipse)将BGLib jar与插件jar打包在一起,Jenkins弄清楚了如何使它们互相看到。

When I build my service jar, however, it doesn't work when I deploy it. 但是,当我构建服务jar时,在部署它时将无法使用。

I run a command like this to install the Tomcat exe renames to myservice.exe: 我运行这样的命令来安装将Tomcat exe重命名为myservice.exe:

d:\myService\bin>myService.exe //IS//myService --Install=D:\myService\bin\myService.exe --Description="run some commands
Java Service" --Jvm=auto --Classpath=D:\myService\jar\myService.jar;D:\myService\jar\BGLib-1.0.jar --StartMode=jvm --
StartClass=com.myCompany.myService.myService --StartMethod=windowsService --StartParams=start --StopMode=jvm --StopClass
=com.myCompany.myService.myService --StopMethod=windowsService --StopParams=stop --LogPath=D:\myService\logs --StdOutpu
t=auto --StdError=auto

When I deploy this with code solely within the myService.jar the service behaves as expected, but when I try to call functions within the BGLib-1.0.jar I get nothing. 当我仅在myService.jar中使用代码部署此服务时,该服务的行为符合预期,但是当我尝试在BGLib-1.0.jar中调用函数时,我什么也没得到。 The jvm appears to crash or become unresponsive. jvm似乎崩溃或无响应。 Debugging is a little tricky but it looks like I am getting class not found errors. 调试有些棘手,但看起来我遇到了类未找到错误。

I tried adding the entry below in the POM file to see if changing the classpath entry in the manifest would help, but it didn't change the manifest. 我尝试将以下条目添加到POM文件中,以查看更改清单中的类路径条目是否有帮助,但并没有更改清单。 I am still kind of clueless ass to how the manifest file works. 我仍然对清单文件的工作方式一无所知。 Any documentation on that would be cool. 关于它的任何文档都很棒。 I have been to Maven's site and it doesn't seem to have comprehensive documentation on the tags available. 我去过Maven的网站,似乎没有关于可用标签的详尽文档。 Is there something I need to change in the manifest to get my jar to see external classes? 我需要更改清单中的内容以使我的jar看到外部类吗? Or is there something I can add that will get Maven to compile the classes from that jar in with my jar? 还是我可以添加一些东西,使Maven与我的jar一起编译该jar中的类?

thanks in advance. 提前致谢。

<configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>com.myCompany.myService.myService</mainClass>
              <customClasspathLayout>BGLib-1.0.jar</customClasspathLayout>
            </manifest>
          </archive>
        </configuration>

To answer mainly the question of the title, you can the shade plugin to include dependencies into your final jar. 要主要回答标题问题,您可以使用shade插件将依赖项包含在最终的jar中。 You can even even relocate the class files (eg change package name) within the final jar so that the included classes don't conflict with different versions of the shaded dependency on the classpath. 您甚至甚至可以在最终jar中重新放置类文件(例如,更改程序包名称),以使所包含的类与类路径上阴影依赖项的不同版本不冲突。 Not sure if this is the best solution for your particular problem though. 虽然不确定这是否是针对特定问题的最佳解决方案。

You can use the maven-dependency-plugin unpack-dependencies goal to include the contents of a dependency in the resulting artifact. 您可以使用maven-dependency-plugin的unpack-dependencies目标依赖项的内容包括在生成的工件中。

An example of how to do this would be: 如何做到这一点的一个例子是:

        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>${project.artifactId}-fetch-deps</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>unpack-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.outputDirectory}</outputDirectory>
                        <stripVersion>true</stripVersion>
                        <excludeTransitive>true</excludeTransitive>
                        <includeArtifactIds>protobuf-java</includeArtifactIds>
                    </configuration>
                </execution>
            </executions>
        </plugin>

This will expand the protobuf-java dependency (flatten it) and include the contents in the resulting artifact generated by your build. 这将扩展protobuf-java依赖性(将其展平),并将内容包含在您的构建生成的结果工件中。

在我看来,您实际上想使用appassembler-maven-plugin ,否则我会去买maven-shade-plugin。

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

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