问题标签 [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.

0 投票
2 回答
10212 浏览

java - 在 Maven 构建中使用 Eclipse Java 编译器 (ecj)

Eclipse 使用它自己的编译器 (ECJ) 来编译 Java 代码。调试用 Eclipse 编译的程序更容易,因为可以立即应用简单的代码更改(通过热代码替换)。

另一方面,Maven 使用(默认情况下)oracle JDK,它生成不同的字节码,防止在 Eclipse 调试会话中进行热代码替换。

因此,如果我打算调试程序,我想在我的 Maven 构建中使用 Eclipse ECJ 编译器。对我来说,一个方便的方法是“ecj”配置文件:

  • 编译发布

    /li>
  • 使用启用的热代码替换编译快照

    /li>

此外,可以在settings.xml甚至 Eclipse 项目属性中指定配置文件激活。

我的问题是:

  1. 这是正确的方法吗?
  2. 如何配置?
  3. 可以为此使用maven工具链吗?
0 投票
1 回答
3991 浏览

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 中的其他类。

0 投票
1 回答
690 浏览

lambda - 无效的方法引用/不明确的引用(javac/ecj 行为差异)

以下代码在使用 Eclipse Compiler for Java 时可以正确编译和运行。

...

使用 javac 编译时,会发出以下错误:

看来这里有两个问题

  • 受保护的方法不能用作方法引用
  • uncheck(...)仅根据返回类型(即 T 或 void)选择正确的方法是不可能的

总体问题是“为什么会有行为差异?”,但也许可以分解为:

  • javac 对方法引用限制是否过于严格,还是 Eclipse 编译器在这里松懈?
  • javac 是否正确确定方法解析不明确,或者它只是缺乏 Eclipse 编译器的智能来正确确定应该选择哪种方法?
0 投票
2 回答
4462 浏览

java - Mockito:使用类型兼容的参数验证重载方法

假设您想使用包含以下方法签名来模拟接口:Mockito

我需要验证(而doThis(Object o)不是其他方法)已被调用一次。

首先,我认为以下行可以解决问题:

但是,由于这似乎在 Windows 上有效,但在 Linux 上却不行,因为在这种环境中,需要调用其他doThis方法。
这是因为该anyObject()参数似乎与两个方法签名都匹配,并且以或多或少不可预测的方式选择了一个。

如何强制Mockito 始终选择doThis(Object o)进行验证?

0 投票
0 回答
485 浏览

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 项目启用了缓存。

难道我做错了什么?

0 投票
1 回答
638 浏览

java - Eclipse/Intellij 中的 Java 多久执行一次“增量编译”?

我知道 Eclipse 使用它自己的 Java (ECJ) 编译器,它能够执行增量编译。从我发现的大多数读数来看,这种编译通常是由保存操作触发的,但这似乎与您在输入单个单元/代码后几乎立即收到编译错误的错误反馈这一事实不符. 我还没有找到任何文档或文献说明触发的粒度(即每个单词、字母、行)?是否正在进行某种额外的背景代码分析?尽管除了语法中的错误检测之外,我看不出它如何能够检测到只能通过编译过程才能发现的语义错误。

0 投票
1 回答
143 浏览

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_2https://git.eclipse.org/c/jdt/eclipse.jdt.core.git/tag/?h=R4_5_2构建标签, 令人惊讶的是它仍然有一个快照版本4.5.2-SNAPSHOT,并且需要相同版本的父级。我可以尝试构建父项目,但我希望它已经在某个存储库等中可用。在继续之前,我至少想知道这条路径是否会通往任何地方。

最后我遇到了Project Tycho,但我认为这只有在我创建一个新插件时才有意义。

0 投票
1 回答
884 浏览

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
0 投票
1 回答
340 浏览

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属性中?

0 投票
3 回答
352 浏览

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 依赖项来做到这一点?


详细代码:这是此代码的简化伪代码单元测试: