我需要使用一个附加构建器来设置一个 Eclipse 项目,该构建器增强了早期构建器(最好是 Eclipse 自己的)生成的 Java 字节码。我设法让这个构建器正确运行并增强了 Eclipse Java 构建器的输出,但几秒钟后 Eclipse 重新运行了它的 Java 构建器并重新设置了字节码。它不会重新运行我的增强生成器。
我的设置
- 作为“Gradle 项目”导入 Eclipse 2019-12(使用 Buildship)。
- 手动(并使用 Gradle 自动添加)自定义Ant构建器(最终调用 Gradle)以增强 Eclipse Java 构建器在 bin/main 中生成的代码。此构建器设置为在Manual Build和Auto Build上运行,而不是After a "Clean"或during a "Clean"。
- 默认情况下,上面的最终有三个构建器,从上到下:1. Gradle Project Builder, 2.Java Builder和 3.我的字节码增强构建器(是的,它在最后列出)。
我尝试过的替代方案
- 将我的构建器设置为在“清洁”之后/期间运行的一些组合也没有成功。不确定这些与哪些确切事件有关,真的。
- 让建造者在之后刷新项目......而且也没有 - 没有帮助。
尝试使用 Gradle 脚本中的以下位删除 Java Builder(不起作用 - 它会自行恢复):
eclipse { project { file { whenMerged { projectFile -> projectFile.buildCommands.removeAll { it.name == 'org.eclipse.jdt.core.javabuilder' } } } } }
尝试手动禁用 Java 构建器并让我的字节码增强构建器也构建文件本身(使用 Gradle)。这将存储
org.eclipse.jdt.core.javabuilder.launch
具有以下内容的以下文件文件...但重新启动构建器时会重新启用:<?xml version="1.0" encoding="UTF-8" standalone="no"?> <launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType"> <booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_DISABLED_BUILDER" value="org.eclipse.jdt.core.javabuilder"/> <mapAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS"/> <booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/> </launchConfiguration>
我尝试(但失败)查找是否有一些工作区文件(而不是项目文件)被更改(以及)以禁用 Java 构建器。
问题
- 为编译后字节码增强设置 Eclipse 的“正确”方法是什么?
- 是什么导致 Eclipse 重新运行以前的构建器而不重新运行我的?
- 有没有办法解决(1)?
- 如何可靠地禁用 Java 构建器?
任何人都可以帮忙吗?谢谢!
更新附加细节 我添加了 12 个构建器,并让它们都将输出附加到同一个日志文件以进行研究。12 个额外的构建器只是提供信息 - 4 个在 Java 构建器之前,4 个在 Java 和增强构建器之间,4 个在增强构建器之后。12 个中的每一个都只在四种条件之一中运行(因此为 3x4)。它们排列如下:
- Gradle 项目生成器
- 1a-after-clean(仅在 "Clean" 之后运行)
- 1b-manual(仅在手动构建期间运行)
- 1c-auto(仅在自动构建期间运行)
- 1d-during-clean(仅在 "Clean" 期间运行)
- Java 生成器
- 2a-after-clean(仅在 "Clean" 之后运行)
- 2b-manual(仅在手动构建期间运行)
- 2c-auto(仅在自动构建期间运行)
- 2d-during-clean(仅在 "Clean" 期间运行)
- 字节码增强生成器
- 3a-after-clean(仅在 "Clean" 之后运行)
- 3b-manual(仅在手动构建期间运行)
- 3c-auto(仅在自动构建期间运行)
- 3d-during-clean(仅在“清洁”期间运行)
12 个信息构建器中的每一个都写下时间、名称和所选测试类的大小。未增强的长度为 46243 字节。增强后它变为 53338 字节长。
这是仅在此项目上运行“清理”后的日志(启用“自动构建”):
20:19:19
1d-during-clean
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:10 Test.class
20:19:19
2d-during-clean
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:10 Test.class
20:19:20
1c-auto
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:10 Test.class
20:19:27
2c-auto
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
Buildfile: /.../some-ant.xml
run-gradle:
[echo] Running Gradle: --parallel :...:enhanceEclipseBytecode
...
[java] > Task :...:enhanceBytecode
[java] Enhanced class: ...Test in ...
...
[java] Enhanced 205 classes.
[java] > Task :...:enhanceEclipseBytecode
[java] BUILD SUCCESSFUL in 15s
[java] 2 actionable tasks: 2 executed
BUILD SUCCESSFUL
Total time: 15 seconds
20:19:44
1c-auto
-rw-r--r-- 1 Learner ...\... 53338 3 Mar 20:19 Test.class
20:19:46
1c-auto
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
20:19:46
2c-auto
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
20:19:46
3b-manual
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
20:19:46
3c-auto
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
20:19:46
3d-during-clean
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
20:19:57
1c-auto
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
20:19:57
2c-auto
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
20:19:57
3b-manual
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
20:19:57
3c-auto
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
20:19:57
3d-during-clean
-rw-r--r-- 1 Learner ...\... 46243 3 Mar 20:19 Test.class
更新 2:重现的最小示例
- 创建一个文件夹 - 随意命名。
在该文件夹中创建包含以下内容的build.grade文件:
buildscript { repositories { mavenCentral() } dependencies { classpath 'org.hibernate:hibernate-gradle-plugin:5.4.2.Final' } } plugins { id 'java' id 'eclipse' } apply plugin: 'org.hibernate.orm' repositories { mavenCentral() } dependencies { implementation 'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final' } hibernate { sourceSets = [ project.sourceSets.main ] enhance { enableLazyInitialization = true; enableDirtyTracking = true; enableAssociationManagement = false; enableExtendedEnhancement = false; } }
在那里也创建一个 src/main/java/learner/TestEntity.java 如下:
package learner; import javax.persistence.*; @Entity public class TestEntity { @Id @Column(name = "id", nullable = false, updatable = false) private Long id = null; @Column(name = "name", columnDefinition = "TEXT") private String name = null; public Long getId() { return id; } public void setId(final Long id) { this.id = id; } public String getName() { return name; } public void setName(final String name) { this.name = name; } }
执行
gradle compileJava
。build/classes/java/main/learner/TestEntity.class
在 ASCII 或十六进制查看器中打开生成的二进制文件并观察$$_hibernate_write_name
其中的内容。- 将此项目作为 Gradle 项目导入 Eclipse(比如 2019-12)并构建它。打开结果
bin/main/learner/TestEntity.class
并观察不到这些。