Jenkins + Play 1.2.4 : cobertura lock files /report 的问题

我们有一个Play 1.2.4应用程序,我们为该应用程序提供了Jenkins(在Ubuntu上)。我们在Cobertura遇到了问题。

运行测试(成功)后,时不时地,我们会收到以下错误:

---------------------------------------
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at net.sourceforge.cobertura.util.FileLocker.lock(FileLocker.java:124)
        at play.modules.cobertura.CoberturaPlugin$CoberturaPluginShutdownThread.run(Unknown Source)
Caused by: java.nio.channels.OverlappingFileLockException
        at sun.nio.ch.FileChannelImpl$SharedFileLockTable.checkList(FileChannelImpl.java:1166)
        at sun.nio.ch.FileChannelImpl$SharedFileLockTable.add(FileChannelImpl.java:1068)
        at sun.nio.ch.FileChannelImpl.lock(FileChannelImpl.java:824)
        at java.nio.channels.FileChannel.lock(FileChannel.java:860)
        ... 6 more
---------------------------------------
Unable to get lock on /var/lib/jenkins/jobs/project/workspace/cobertura.ser.lock: null
This is known to happen on Linux kernel 2.6.20.
Make sure cobertura.jar is in the root classpath of the jvm 
process running the instrumented code.  If the instrumented code 
is running in a web server, this means cobertura.jar should be in 
the web server's lib directory.
Don't put multiple copies of cobertura.jar in different WEB-INF/lib directories.
Only one classloader should load cobertura.  It should be the root classloader.
---------------------------------------
lock file could not be deleted

这似乎不会“破坏构建”,但进一步构建,我们得到以下内容(这会导致cobertura报告失败)

Publishing Cobertura coverage report...
No coverage results were found using the pattern 'test-result/code-coverage/coverage.xml' relative to '/var/lib/jenkins/jobs/project/workspace'.  Did you enter a pattern relative to the correct directory?  Did you generate the XML report(s) for Cobertura?
Build step 'Publish Cobertura Coverage Report' changed build result to FAILURE

手动运行后续生成通常会通过。

根据cobertura 1.9.2的零代码覆盖率,但测试正在工作,我尝试在播放auto-test-command后设置-Dcobertura.use.java.nio=false

由于此错误只是不时发生,因此我不完全确定这是否有帮助。但在那之后,我们遇到了播放自动测试挂起的问题:

  ...
  Executing /opt/play-1.2.4/play auto-test "/var/lib/jenkins/jobs/project/workspace"  -Dcobertura.use.java.nio=false
  [workspace] $ /opt/play-1.2.4/play auto-test "/var/lib/jenkins/jobs/project/workspace" -Dcobertura.use.java.nio=false
  <build stuck here for a couple of days>

由于没有什么是完全确定性的,所以在这里说因果关系有点困难。(这似乎发生在 jenkins/服务器重新启动后的一两次构建之后)

目前,我正在考虑在我们的项目中禁用Cobertura,但如果有人有其他想法,那就太好了=)


答案 1

显然,这是由于 JVM 实现中的 JVM 锁定问题,或者更确切地说,是由于您部署 cobertura JAR 的方式。

Jenkins 可以生成很多 JVM 线程,如果 cobetura 在你的全局类路径上,则可能会发生一些奇怪的冲突。

我假设,最终,这应该归因于cobertura中的一个小错误(除非复杂的corbertura文件锁定正在解决其他一些更重要的问题)。

根据Cobertura的FileLock(cobertura/src/main/java/net/sourceforge/cobertura/util/FileLocker.java)的源代码,多个JVM加载Cobertura jar存在一些问题。

要解决此问题,请确保只有一个副本和一个应用程序启动并使用Corbetura。

您的 VM 实现修复它的原因很可能是,您已经减少了 cobetrura 加载方式的可变性。此外,您可能正在以更高的频率重新启动 VM,而不是 jenkins 服务器。

在我们的 jenkins corbertura 版本中,我们只使用 maven 插件,这似乎可以正常工作,没有问题(但话说回来,我们没有使用 java 1.7,也没有使用 Play)。


答案 2

这已经困扰了我们一段时间(播放1.2.4 / Jenkins)。由于 jenkins cobertura 插件(报告发布)和 play framework cobertura 模块之间的序列重叠,存在一些问题。我相信这纯粹是时间上的巧合,因此是间歇性的。对于缺乏更好的解决方案,我们有以下工作。

从主构建作业中删除了 jenkins cobertura 报告发布操作。我们创建了一个新的 jenkins 作业,该作业设置了发布 cobertura 覆盖率报告操作。在新作业中,我们有 shell 操作将覆盖率从主生成作业工作区复制到新作业的工作区.xml以运行 cobertura 覆盖率报告发布操作。复制(出于明显的原因)是为了避免在同一个工作中同时运行play cobertura和jenkins cobertura。

它不是最好的,但很高兴看到报道报告/图表:-)


推荐