问题标签 [ecj]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 在 Maven 构建中使用 Eclipse Java 编译器 (ecj)
Eclipse 使用它自己的编译器 (ECJ) 来编译 Java 代码。调试用 Eclipse 编译的程序更容易,因为可以立即应用简单的代码更改(通过热代码替换)。
另一方面,Maven 使用(默认情况下)oracle JDK,它生成不同的字节码,防止在 Eclipse 调试会话中进行热代码替换。
因此,如果我打算调试程序,我想在我的 Maven 构建中使用 Eclipse ECJ 编译器。对我来说,一个方便的方法是“ecj”配置文件:
编译发布
/li>使用启用的热代码替换编译快照
/li>
此外,可以在settings.xml
甚至 Eclipse 项目属性中指定配置文件激活。
我的问题是:
- 这是正确的方法吗?
- 如何配置?
- 可以为此使用maven工具链吗?
java - 由于依赖项无效,无法加载类 org.eclipse.jdt.core.JDTCompilerAdapter
我正在创建一个 java 代理,用于对某些类进行一些字节码修改,org.eclipse.jdt.core.JDTCompilerAdapter
就是其中之一。我正在使用 javassit 来execute()
修改org.eclipse.jdt.core.JDTCompilerAdapter
. 所以我在我的代理项目中包含了 ecj(使用 gradle)
因为我需要使用 ecj 的一些类。
代理的目标是拦截对execute方法的调用,修改execute方法以在我的一些类中添加一些调用,以触发一些处理。
我正在针对具有 2 个类的简单 java 项目测试代理。该项目是用 ant 构建的,并JDTCompilerAdapter
用作编译器。
这是 build.xml 文件
该代理将在构建项目时使用。因此,为了测试代理,我使用以下命令:
build_wrapper.sh 包含这个(我添加了 ecj 依赖项,所以我可以JDTCompilerAdapter
像在 bulid.xml 中一样 编译项目<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
:
这个想法是代理包装器将解析参数(outdir 用于生成一些东西,而 exec 是用于启动我的测试项目的构建的脚本)获取要执行的命令build_wrapper.sh
(在这种情况下 ../ant/bin/ant -lib ../eclipse/plugins/ecj-4.3.1.jar build-e
)并添加它自己作为命令的java代理。
该问题发生在代理执行期间。这是输出:
当我不在代理项目中使用 ecj-4.3.1.jar 时,构建运行良好我拦截了对execute()
方法的调用,但我不能使用 ecj jar 中的其他类。
lambda - 无效的方法引用/不明确的引用(javac/ecj 行为差异)
以下代码在使用 Eclipse Compiler for Java 时可以正确编译和运行。
...
使用 javac 编译时,会发出以下错误:
看来这里有两个问题
- 受保护的方法不能用作方法引用
uncheck(...)
仅根据返回类型(即 T 或 void)选择正确的方法是不可能的
总体问题是“为什么会有行为差异?”,但也许可以分解为:
- javac 对方法引用限制是否过于严格,还是 Eclipse 编译器在这里松懈?
- javac 是否正确确定方法解析不明确,或者它只是缺乏 Eclipse 编译器的智能来正确确定应该选择哪种方法?
java - Mockito:使用类型兼容的参数验证重载方法
假设您想使用包含以下方法签名来模拟接口:Mockito
我需要验证(而doThis(Object o)
不是其他方法)已被调用一次。
首先,我认为以下行可以解决问题:
但是,由于这似乎在 Windows 上有效,但在 Linux 上却不行,因为在这种环境中,需要调用其他doThis
方法。
这是因为该anyObject()
参数似乎与两个方法签名都匹配,并且以或多或少不可预测的方式选择了一个。
如何强制Mockito 始终选择doThis(Object o)
进行验证?
playframework - 在虚拟机上运行时,Play 框架不会自动重新加载更改
问题
我正在使用 Play Framework,并且在虚拟机上这样做。但是 Play 不会根据开发模式的更改重新编译。
我已经尝试在激活器控制台中使用run
和。~run
当我这样做~run
时,只要我在编辑器中点击保存,它就会正确重新编译更改的文件。但是当我刷新浏览器时,它不会显示更改。例如,我可能会编辑一个 scala 模板,但刷新浏览器时文本保持不变。如果我在重新编译我的更改后执行 Ctrl+D,它将重新编译一些类,然后重新加载页面,并正确显示更改。
当我这样做run
时,当我在更改代码后在浏览器中点击刷新时,它根本不会编译更改,只有在执行 Ctrl+D 时
我的设置
我正在运行配置有 Vagrant 的 VirtualBox 虚拟机。我在主机和 VM 之间的共享文件夹中运行代码,以便用户可以在主机上使用他喜欢的 IDE。我在虚拟机上运行数据库和播放。我将主机上的 8001 端口转发到 VM 上的 9000 端口,我可以通过这种方式正确使用我的应用程序并与之交互。唯一不起作用的是自动重新加载。
当我在主机上运行 Play 安装的代码时,自动重新加载编译并正确显示所有更改。我只有在 VM 上运行 Play 时遇到问题。我尝试在几台 Linux 和 Windows 主机上运行相同的 VM 设置,它们都显示同样的问题。
此 Play 项目启用了缓存。
难道我做错了什么?
java - Eclipse/Intellij 中的 Java 多久执行一次“增量编译”?
我知道 Eclipse 使用它自己的 Java (ECJ) 编译器,它能够执行增量编译。从我发现的大多数读数来看,这种编译通常是由保存操作触发的,但这似乎与您在输入单个单元/代码后几乎立即收到编译错误的错误反馈这一事实不符. 我还没有找到任何文档或文献说明触发的粒度(即每个单词、字母、行)?是否正在进行某种额外的背景代码分析?尽管除了语法中的错误检测之外,我看不出它如何能够检测到只能通过编译过程才能发现的语义错误。
eclipse - 如何获取 Eclipse Compiler for Java 批处理包 4.5.2+
版本4.5.1
是中央提供的最后一个版本 - http://mvnrepository.com/artifact/org.eclipse.jdt.core.compiler/ecj/4.5.1
不幸的是,有一个令人讨厌的错误,仅在4.5.2
.
我似乎在任何地方都找不到二进制包。我尝试从源代码构建它但失败了(详情如下)。获取 4.5.2 二进制文件的推荐方法是什么?
我试过https://github.com/eclipse/eclipse.jdt.core但它没有任何相关标签。
我尝试R4_5_2
从https://git.eclipse.org/c/jdt/eclipse.jdt.core.git/tag/?h=R4_5_2构建标签,
令人惊讶的是它仍然有一个快照版本4.5.2-SNAPSHOT
,并且需要相同版本的父级。我可以尝试构建父项目,但我希望它已经在某个存储库等中可用。在继续之前,我至少想知道这条路径是否会通往任何地方。
最后我遇到了Project Tycho,但我认为这只有在我创建一个新插件时才有意义。
java-8 - 对原始类型的方法引用有害吗?
下面的代码包含对Enum::name
(注意没有类型参数)的引用。
Javac 编译时报警告:
[警告] 找到原始类型:java.lang.Enum 缺少泛型类 java.lang.Enum 的类型参数
将表达式更改为Enum<T>::name
会导致警告消失。
然而,IdeaEnum<T>::name
用以下警告标记版本:
可以推断出显式类型参数
反过来,Eclipse (ECJ) 没有报告任何一种配方的任何问题。
三种方法哪一种是正确的?
一方面,原始类型相当讨厌。如果您尝试放置一些其他类型的参数,例如 Enum<Clause>::name
将导致编译失败,那么这是一些额外的保护。
另一方面,上面的引用等同于e -> e.name()
lambda,并且这个公式不需要类型参数。
环境:
- Java 8u91
- IDEA 15.0.3 社区
- 欧洲法院 4.5.2
java - 使用 Eclipse 编译器编译时 LocalVariableTypeTable 中出现奇怪的“!*”条目
让我们使用 Eclipse Mars.2 包中的 ECJ 编译器编译以下代码:
编译命令如下:
$ java -jar org.eclipse.jdt.core_3.11.2.v20160128-0629.jar -8 -g Test.java
编译成功后,让我们检查生成的类文件javap -v -p Test.class
。最有趣的是为(a, t) -> {}
lambda 生成的合成方法:
!*
看到这个条目我很惊讶LocalVariableTypeTable
。JVM 规范涵盖LocalVariableTypeTable 属性并说:
该
constant_pool
索引处的条目必须包含一个CONSTANT_Utf8_info
结构(第 4.4.7 节),该结构表示一个字段签名,该签名对源程序中的局部变量的类型进行编码(第 4.7.9.1 节)。
§4.7.9.1定义了字段签名的语法,如果我理解正确,它不涵盖任何类似于!*
.
还应该注意的是,javac 编译器和较早的 ECJ 3.10.x 版本都不会生成此条LocalVariableTypeTable
目。是!*
一些非标准的 Eclipse 扩展还是我在 JVM 规范中遗漏了一些东西?这是否意味着 ECJ 不符合 JVM 规范?实际上是什么!*
意思,是否有任何其他类似的字符串可能出现在LocalVariableTypeTable
属性中?
java - 在运行时确定 String 中 Java 表达式的返回类型
在运行时,在我的 Java 程序中,给定一个字符串,我想知道返回类型。例如:
1 + 1
返回int
1L + 1L
返回long
1L + 1
返回long
1 + 1.5
返回double
1 + 2 - 3 * 4 / 5
返回int
1 / 0
返回int
1 + Math.nextInt()
返回int
1.5 + Math.nextInt()
返回double
Color.RED
返回java.awt.Color
- 鉴于这
a
是一个 int:a + 1
返回int
- 鉴于这
a
是一个 int:a + 1.5
返回double
无需实际评估代码:我只需要返回类型。如何使用 JDK 运行时编译器、ECJ JDT 或任何其他纯 Java 依赖项来做到这一点?
详细代码:这是此代码的简化伪代码单元测试: