【发布时间】:2015-07-17 13:06:10
【问题描述】:
我正在使用 Eclipse,并且我有一个多模块 Maven 项目,其中我使用 Lombok(1.16.4) Java=jdk1.7.0_71。
在 Eclipse 中,我的所有代码都可以编译并且 JUnit 测试通过。但是在 Maven(v. 3.2.3 和 3.3.3)中,代码无法编译。
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] DetermineMarketDirection.java:[86,42] cannot find symbol
symbol: method sumValuesDouble(java.lang.String)
location: variable listToWorkOn of type java.util.List<T>
[INFO] 1 error
这个sumValuesDouble 是我的Lombok 对List<> 类型的扩展方法,它在module A 中定义。上述错误发生在module C 中,这取决于module A。
这是ExtensionList.java的一部分:
public static <T> Double sumValuesDouble(List<T> list, final String methodName) {
return sumValuesOf(list, methodName, Double.class);
}
private static <T, N extends Number> N sumValuesOf(List<T> list, final String methodName, Class<N> type) {
Function<T, N> transform = new Function<T, N>() {
@SuppressWarnings("unchecked")
@Override
@SneakyThrows
public N apply(T from) {
Method method = from.getClass().getMethod(methodName);
return (N) method.invoke(from);
}
};
List<N> projectedList = Lists.transform(list, transform);
return sumAll(projectedList);
}
这很奇怪,因为我在Module A 中对此扩展方法进行了测试,它们编译正常并通过了。
来自Module A的部分测试:
@ExtensionMethod({ ExtensionList.class })
public class ExtensionListSumAllTest {
@Test
public void testDouble() {
List<ValueDouble> listDouble = new ArrayList<>();
listDouble.add(new ValueDouble(1, 1d));
listDouble.add(new ValueDouble(2, 2d));
listDouble.add(new ValueDouble(3, 3d));
Double actual = listDouble.sumValuesDouble("getValue");
final Double expected = 6d;
assertEquals(expected, actual);
}
@AllArgsConstructor
@Getter
public class ValueDouble {
private final Integer id;
private final Double value;
}
}
我该怎么做才能让 Maven “看到”这个方法?
顺便说一句:我在module c 中使用了很多扩展方法,而 Maven 只对那个有问题。同样在这个项目/eclipse中我使用Lombok很长时间了,之前没有遇到过这样的问题。
更新:
我玩了一点,我发现,当我在执行扩展方法之前添加“虚拟”代码时,maven 编译代码没有问题。
所以,这不会编译
@Slf4j
@ExtensionMethod({ ExtensionList.class })
public class SmaCalculator {
static <C extends Candle> double calculateSMA(List<C> candles, int sma) {
List<C> listToWorkOn = prepareListForSmaCalculation(candles, sma);
Double sum = listToWorkOn.sumValuesOf("getClosePrice");
Double smaValue = sum / sma;
return smaValue;
}
...other methods...
}
但是这通过 Maven 编译成功,dupa 对象甚至没有引用listToWorkOn 对象:
static <C extends Candle> double calculateSMA(List<C> candles, int sma) {
List<C> listToWorkOn = prepareListForSmaCalculation(candles, sma);
List<C> dupa = new ArrayList<C>();
dupa.add(listToWorkOn.first());
dupa.sumValuesOf("getClosePrice");
Double sum = listToWorkOn.sumValuesOf("getClosePrice");
Double smaValue = sum / sma;
return smaValue;
}
【问题讨论】: