当前位置: 首页 > 知识库问答 >
问题:

使用SpEL的@CacheEvit注释在Eclipse编译后工作,但在Ant编译后不工作

戚学
2023-03-14

我有一个类,它使用Spring@CacheEvit注释和嵌入的Spring表达式语言。当我允许这个类由Eclipse自动编译时,一切都很好。但是,当我使用Ant任务进行编译时(通过Eclipse或从命令行),生成的.class文件不起作用,并抛出一个异常,这似乎是一个转移注意力的异常。

我的问题是:如何配置Ant构建,使其生成working.class工件(这样其他开发人员就可以在不需要Eclipse的情况下构建我的项目)?Eclipse和Ant之间的配置似乎是相同的,但我一定是在某个地方缺少了一些属性。

    null

/src/sample/sampleAction.java:包含使用@CacheEvit注释和SPEL的方法。

package sample;
import org.springframework.cache.annotation.CacheEvict;

public class SampleAction {
    @CacheEvict(value = "sampleCache", allEntries = true, condition = "#string.bytes != null")
    public void triggerCache(String string) {
        System.out.println("triggerCache(" + string + ")");
    }
}

/src/sample/sampleActionTest.java:一个单元测试,它可以使用Eclipse工件,但不能使用Ant工件。

package sample;
import org.junit.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"application.xml"})
public class SampleActionTest {
    @Autowired
    private SampleAction sampleAction;

    @Test
    public void testCacheMethod() {
        sampleAction.triggerCache("Definitely not a null string.");
    }
}

/src/sample/application.xml:缓存和action类的Spring定义文件。

<cache:annotation-driven />
<bean id="sampleAction" class="sample.SampleAction" />
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
    <property name="caches">
        <set>
            <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="sampleCache" />
        </set>
    </property>
</bean>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
<path id="classpath.main">
    <fileset dir="lib" includes="*.jar" />
</path>
<path id="classpath.test">
    <path refid="classpath.main" />
    <pathelement location="output/classes" />
</path>

<target name="compileFailure" description="Cleans, compiles, and runs a unit test, which fails.">
    <delete quiet="true" dir="output/classes" />
    <mkdir dir="output/classes" />      
    <copy tofile="output/classes/sample/application.xml" file="src/sample/application.xml" />
    <javac srcdir="src" destdir="output/classes"
        classpathref="classpath.main" source="1.6" target="1.6" includeantruntime="false" />
    <junit printsummary="yes">
        <classpath refid="classpath.test" />
        <formatter type="plain" usefile="false"/>
        <test name="sample.SampleActionTest" outfile="result" />
    </junit>
</target>
com.springsource.org.aopalliance-1.0.0.jar
commons-logging-1.1.3.jar
junit-4.10.jar
spring-aop-3.2.2.jar
spring-beans-3.2.2.jar
spring-context-3.2.2.jar
spring-context-support-3.2.2.jar
spring-core-3.2.2.jar
spring-expression-3.2.2.jar
spring-test-3.2.2.jar

这个存根项目也可以作为一个ZIP归档文件使用,包括支持Spring和JUnit的JAR文件:Minimal Eclipse项目

  1. 在eclipse中打开“CompilerDebug”项目。
  2. 允许Eclipse自动构建“sample”包中的类。要么进行项目清理/构建,要么打开Java文件,编辑空白,然后重新发送它们。使用Eclipse编译时,output/classes/sample/sampleAction.class为911字节。
  3. 右键单击“SampleActionTest”并选择“Run as...JUnit Test”。测试成功通过。
  4. 在Ant视图中打开build.xml文件。右键单击“CompileFailure”目标并选择“Run as...Ant Build”。测试失败,导致堆栈跟踪“EL1007E:(POS0):在NULL上找不到字段或属性'Bytes'”。使用Ant编译时,output/classes/sample/sampleAction.class为694字节。
  1. 我尝试将compiler=“org.Eclipse.jdt.core.jdtCompilerAdapter”添加到“javac”任务中,以便强制Ant使用Eclipse编译器,但是在此更改之后单元测试仍然失败。SampleAction.class在这里是696字节。
  2. 如果我从@CacheEvict注释中删除该条件,则单元测试通过两个编译器。
  3. 将源/目标级别设置为1.5或1.7无效。
  4. 强制Ant任务“在与工作区相同的JRE中运行”没有效果。
  5. 下载独立的Ant发行版(1.9.1)并运行与Eclipse完全隔离的Ant构建没有影响。
  6. 用声明性XML配置(使用aspectjtools)替换@CacheEvit注释没有效果。

见下文提供的答复。Ant在使用Javac编译时没有显式地将调试模式设置为true。为了正确地处理注释,SpEL需要在类文件中包含额外的调试信息。将debug设置为true立即纠正了该问题。

<javac debug="true" [...] />

共有1个答案

平光明
2023-03-14

似乎SpEL需要java编译器在类文件中设置调试信息才能工作。我有一个类似的问题,在我启用在maven构建中生成调试信息后,这个问题得到了解决。Eclipse编译器自动执行此操作。

 类似资料:
  • 我刚刚在Eclipse(Oxygen 4.7.3a,Ubuntu 18.04上)中用Scala-IDE插件(4.7.0.v-2_12-201709291352-71A28D0)和一个简单的HelloWorld对象建立了一个Scala项目。如果我将“properties->Scala compiler”设置为2.12,那么一切都将按照预期工作:项目将编译并运行。但是如果我选择任何其他版本(例如,“最

  • 如果你不知道怎么从 github 上下载 Nutz 的源代码,请看 从 Git 编译 一节 编译通常是个麻烦的问题,依赖关系啊,环境变量啊,等等,全是些没有技术含量的东 东,但是却能搞的你非常头疼。虽然编译 Nutz 是一个相对简单的工作 -- 它编译 的时候不需要依赖第三方 jar 包,但是还是有一些工作要做的。 从我个人的情况来看,我经常在如下三个环境下进行 Nutz 的开发: 公司 - Vi

  • 后编译指的是应用依赖的 NPM 包并不需要在发布前编译,而是随着应用编译打包的时候一块编译。 注: 关于后编译更详细内容可参阅 webpack 应用编译优化之路 背景 使用 webpack + babel 开发应用越来越多,而且一般都是通过 NPM 进行包管理的,这样依赖包越来越多,这些依赖包也是使用的 ES2015+ 开发的,所以每个依赖包都需要编译才能发布,这样编译后代码中往往后包含很多编译代

  • 我们有一个相当大的项目,使用maven、Spring boot、querydsl、lombok。我有两个分支,两个版本都编译成功。(>使用@Sl4j生成的log或。 我甚至不知道从哪里开始,所以任何关于如何确定错误的提示都是非常好的。当然,您还需要哪些进一步的信息来帮助? 编辑感谢到目前为止的提示,我现在尝试调整我们的pom。xml配置,使lombok由maven编译器插件的annotationP

  • 问题内容: 我不得不发现我的项目中有Java代码,该代码可以在Eclipse中编译并正常运行,但是会在javac中引发编译错误。 一个完整的代码段: javac中的编译返回: 现在,此错误阻止在Maven中构建项目。由于Eclipse编译器具有更高的容忍度,因此我现在不得不假设代码段的定义和用法如上所述,静态方法不是有效的Java吗? 问题答案: 似乎Sun的1.6 JDK无法推断正确的类型。以下

  • null 代码(步骤1和2): 实际上,第一个任务执行良好,并为注释处理器实现编译.class文件。它在第二个任务停止。 Ant说: Java 1.6 Ant 1.8.2