在Quarkus中使用Infinispan Embedded和Infinispan jCache时会抛出:
构建步骤io.quarkus.arc.deployment.ArcAnnotationProcessor#build抛出了一个异常:javax.enterprise.inject.spi.DefinitionException:拦截器没有绑定:org.infinispan.jcache.annotation.CacheRemoveEntryInterceptor
我尝试使用hazelcast,但没有成功,并且存在相同的问题。
我的pom.xml:
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo</groupId>
<artifactId>bar</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<jersey-common.version>2.22.2</jersey-common.version>
<javac.version>1.8.0-u20</javac.version>
<surefire-plugin.version>2.22.0</surefire-plugin.version>
<quarkus.version>0.14.0</quarkus.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<lombok.version>1.18.6</lombok.version>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bom</artifactId>
<version>${quarkus.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-rest-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-opentracing</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>${jersey-common.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>javac</artifactId>
<version>${javac.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-fault-tolerance</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-cdi-embedded</artifactId>
<version>9.4.9.Final</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-jcache</artifactId>
<version>9.4.9.Final</version>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<uberJar>true</uberJar>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.version}</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<configuration>
<enableHttpUrlHandler>true</enableHttpUrlHandler>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemProperties>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
我的service.java
@ApplicationScoped
public class Service {
@CacheResult
public String getString(final String key) {
return new String(key + " - " + System.currentTimeMillis());
}
}
当我尝试使用Quarkus启动
./mvnw compile quarkus:dev
发生此异常:
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------------< com.foo:bar >----------------------------
[INFO] Building bar 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ bar ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 3 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ bar ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 23 source files to /home/user/git/foo-bar/foo-bar-q/target/classes
[INFO]
[INFO] --- quarkus-maven-plugin:0.14.0:dev (default-cli) @ bar ---
Listening for transport dt_socket at address: 5005
23:40:46,376 INFO [io.qua.dep.QuarkusAugmentor] Beginning quarkus augmentation
23:40:46,627 INFO [org.jbo.threads] JBoss Threads version 3.0.0.Alpha4
23:40:47,094 ERROR [io.qua.dev.DevModeMain] Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.arc.deployment.ArcAnnotationProcessor#build threw an exception: javax.enterprise.inject.spi.DefinitionException: Interceptor has no bindings: org.infinispan.jcache.annotation.CacheRemoveEntryInterceptor
at io.quarkus.runner.RuntimeRunner.run(RuntimeRunner.java:137)
at io.quarkus.dev.DevModeMain.doStart(DevModeMain.java:131)
at io.quarkus.dev.DevModeMain.main(DevModeMain.java:84)
Caused by: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.arc.deployment.ArcAnnotationProcessor#build threw an exception: javax.enterprise.inject.spi.DefinitionException: Interceptor has no bindings: org.infinispan.jcache.annotation.CacheRemoveEntryInterceptor
at io.quarkus.builder.Execution.run(Execution.java:124)
at io.quarkus.builder.BuildExecutionBuilder.execute(BuildExecutionBuilder.java:137)
at io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:108)
at io.quarkus.runner.RuntimeRunner.run(RuntimeRunner.java:102)
... 2 more
Caused by: javax.enterprise.inject.spi.DefinitionException: Interceptor has no bindings: org.infinispan.jcache.annotation.CacheRemoveEntryInterceptor
at io.quarkus.arc.processor.Interceptors.createInterceptor(Interceptors.java:47)
at io.quarkus.arc.processor.BeanDeployment.findInterceptors(BeanDeployment.java:719)
at io.quarkus.arc.processor.BeanDeployment.<init>(BeanDeployment.java:133)
at io.quarkus.arc.processor.BeanProcessor.process(BeanProcessor.java:150)
at io.quarkus.arc.deployment.ArcAnnotationProcessor.build(ArcAnnotationProcessor.java:259)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at io.quarkus.deployment.ExtensionLoader$1.execute(ExtensionLoader.java:507)
at io.quarkus.builder.BuildContext.run(BuildContext.java:414)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1998)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1525)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1416)
at java.lang.Thread.run(Thread.java:748)
at org.jboss.threads.JBossThread.run(JBossThread.java:479)
答案 0 :(得分:1)
所以我认为问题在于javax.cache.annotation.CacheRemove
本身不是拦截器绑定。它由Infinispan JCache extension另外注册。但是,Quarkus / ArC不支持CDI便携式扩展,并且目前无法将任意注释注册为拦截器绑定。
我已经创建了this Quarkus issue。
答案 1 :(得分:0)
我知道这不是最好的方法,但是目前它正在起作用。
我能够像这样在quarkus中使用内置缓存:
Pom.xml
<properties>
<quarkus.version>0.14.0</quarkus.version>
<commons-jcs-jcache.version>2.2.1</commons-jcs-jcache.version>
<hazelcast.version>3.12</hazelcast.version>
<cache-api.version>1.0.0</cache-api.version>
</properties>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jcs-jcache</artifactId>
<version>${commons-jcs-jcache.version}</version>
<classifier>cdi</classifier>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>${cache-api.version}</version>
</dependency>
新的注释JCache:
@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface JCache {
}
新的Interceptor扩展JCache官方类:
(PS:那是我可以使拦截器正常工作的唯一方法。)
import org.apache.commons.jcs.jcache.cdi.CacheResultInterceptor;
import javax.cache.annotation.CacheResult;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Interceptor
@JCache
@CacheResult
public class JCacheCacheResultInterceptor extends CacheResultInterceptor {
@AroundInvoke
public Object processRequest(final InvocationContext invocationContext) throws Throwable {
return super.cache(invocationContext);
}
}
我需要创建一个生产者,以便生成一些依赖项。
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.eviction.LFUEvictionPolicy;
import org.apache.commons.jcs.jcache.cdi.CDIJCacheHelper;
import org.apache.commons.jcs.jcache.cdi.MakeJCacheCDIInterceptorFriendly;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import static com.hazelcast.config.MaxSizeConfig.MaxSizePolicy.PER_NODE;
@ApplicationScoped
public class InMemoryCacheFactory {
HazelcastInstance instance;
// This setup is not workink! The cache never expires regardless of this setting
@PostConstruct
public void afterCreate() {
final Config config = new Config();
final LFUEvictionPolicy mapEvictionPolicy = new LFUEvictionPolicy();
config.getMapConfig("default")
.setTimeToLiveSeconds(5)
.setMaxIdleSeconds(10)
.setMapEvictionPolicy(mapEvictionPolicy)
.getMaxSizeConfig().setMaxSizePolicy(PER_NODE)
.setSize(10000);
this.instance = Hazelcast.newHazelcastInstance(config);
}
@PreDestroy
public void beforeDestroy() {
if(this.instance != null) {
this.instance.shutdown();
}
}
@Produces
@ApplicationScoped
public HazelcastInstance getInstance() {
return this.instance;
}
@Produces
public MakeJCacheCDIInterceptorFriendly getMakeJCacheCDIInterceptorFriendly() {
return new MakeJCacheCDIInterceptorFriendly();
}
@Produces
public CDIJCacheHelper getCDIJCacheHelper() {
return new CDIJCacheHelper();
}
}
使用缓存:
(仅适用于两个注释:@JCache和@CacheResult)
import com.foo.bar.JCache;
import org.apache.commons.collections.CollectionUtils;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import javax.annotation.PostConstruct;
import javax.cache.annotation.CacheDefaults;
import javax.cache.annotation.CacheResult;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.io.Serializable;
import java.util.stream.Collectors;
@ApplicationScoped
@CacheDefaults(cacheName = "default")
public class FooService {
@JCache
@CacheResult
public List<String> getList() {
System.out.println("Not using the cache...");
List<String> strings = Arrays.asList("foo", "bar", "baz");
return strings;
}
}
一些要点:
@BuildStep
void setupResourceInjection(BuildProducer<ResourceAnnotationBuildItem> resourceAnnotations, BuildProducer<GeneratedResourceBuildItem> resources) {
resources.produce(new GeneratedResourceBuildItem("META-INF/services/io.quarkus.arc.ResourceReferenceProvider",
JPAResourceReferenceProvider.class.getName().getBytes()));
resourceAnnotations.produce(new ResourceAnnotationBuildItem(DotName.createSimple(PersistenceContext.class.getName())));
}