使用Redisson创建缓存时出现InaccessibleObjectException

问题描述 投票:0回答:1

我正在尝试将 Redisson 设置为用于bucket4j,并在 JVM 17 上运行我的 Spring Boot 2.7.3 应用程序。目前,我正在使用单元测试来让所有内容都在某个合理的水平上工作,但显然需要一个稍后真正实施。

进入代码...

@Configuration
@EnableCaching
public class Bucket4JConfig {
    public static final String CACHE_NAME = "r_quota_";

    @Bean
    public Config envConfig() {
        var port = "6379";
        var host = "localhost";
        BinaryOperator<String> getUrl = (h, p) -> String.format("redis://%s:%s", h, p);
        Config config = new Config();
        config.useReplicatedServers()
                .setReadMode(ReadMode.SLAVE)
                .addNodeAddress(getUrl.apply(host, port));
        return config;
    }

    @Bean(name = "javaxCacheManager")
    public CacheManager cacheManager() {
        return Caching.getCachingProvider().getCacheManager();
    }

    @Bean
    public ProxyManager<String> proxyManager(CacheManager cacheManager, Config config) {
        Cache<String, byte[]> cache = cacheManager.getCache(CACHE_NAME);
        if (cache == null) {
            MutableConfiguration<String, byte[]> jcacheConfig = new MutableConfiguration<>();
            jcacheConfig.setExpiryPolicyFactory(null); // never expire
            javax.cache.configuration.Configuration<String, byte[]> redissonConfiguration = RedissonConfiguration.fromConfig(config, jcacheConfig);
            cache = cacheManager.createCache(CACHE_NAME, redissonConfiguration);
        }
        return new JCacheProxyManager<>(cache);
    }

    @Bean
    @Primary
    public SyncCacheResolver bucket4jCacheResolver(CacheManager cacheManager) {
        return new JCacheCacheResolver(cacheManager);
    }

    @Bean
    public JCacheManagerCustomizer jCacheManagerCustomizer(Config config) {
        return cacheManager -> cacheManager.createCache(CACHE_NAME, RedissonConfiguration.fromConfig(config));
    }
}
@Service
public class RateLimitService {

    private static final int QUOTA = 2;
    private final ProxyManager<String> buckets;

    public RateLimitService(ProxyManager<String> buckets) {
        this.buckets = buckets;
    }

    public void blockOnBucket(String bucketName) throws InterruptedException {
        resolveBucket(bucketName).asBlocking().consume(1);
    }

    private Bucket resolveBucket(String bucketName) {
        Supplier<BucketConfiguration> confSupplier = () -> {
            return BucketConfiguration.builder()
                    .addLimit(limit -> limit.capacity(QUOTA).refillGreedy(QUOTA, Duration.ofSeconds(1)))
                    .build();
        };
        return buckets.builder().build(bucketName, confSupplier);
    }
}
public class Bucket4JOverRedissonTest {

    private RateLimitService rateLimitService;

    @BeforeEach
    public void setUp() {
        Bucket4JConfig conf = new Bucket4JConfig();
        var config = conf.envConfig();
        var cacheManager = conf.cacheManager();
        System.out.printf("Caches: [%s]", Streams.stream(cacheManager.getCacheNames()).collect(Collectors.joining(",")));
        rateLimitService = new RateLimitService(conf.proxyManager(cacheManager, config));
    }

    @Test
    public void test() throws InterruptedException {
        String bucketName = "LIMITED_RESOURCE";
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();;
        rateLimitService.blockOnBucket(bucketName);
        rateLimitService.blockOnBucket(bucketName);
        rateLimitService.blockOnBucket(bucketName);
        stopWatch.stop();

        Assertions.assertTrue(stopWatch.getTotalTimeMillis() > 1000);

    }
}

我将这些行添加到我的 pom.xml 中:

        <dependency>
            <groupId>com.bucket4j</groupId>
            <artifactId>bucket4j_jdk17-redis-common</artifactId>
            <version>8.11.1</version>
        </dependency>
        <dependency>
            <groupId>com.bucket4j</groupId>
            <artifactId>bucket4j_jdk17-redisson</artifactId>
            <version>8.11.1</version>
        </dependency>
        <dependency>
            <groupId>com.giffing.bucket4j.spring.boot.starter</groupId>
            <artifactId>bucket4j-spring-boot-starter</artifactId>
            <version>0.12.6</version>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>2.15.2</version>
        </dependency>

我不断遇到异常:

java.lang.reflect.InaccessibleObjectException: Unable to make field private final byte[] java.lang.String.value accessible: module java.base does not "opens java.lang" to unnamed module @1d371b2d

    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
    at org.nustaq.serialization.FSTClazzInfo.createFieldInfo(FSTClazzInfo.java:504)
    at org.nustaq.serialization.FSTClazzInfo.createFields(FSTClazzInfo.java:367)
    at org.nustaq.serialization.FSTClazzInfo.<init>(FSTClazzInfo.java:128)
    at org.nustaq.serialization.FSTClazzInfoRegistry.getCLInfo(FSTClazzInfoRegistry.java:129)
    at org.nustaq.serialization.FSTClazzNameRegistry.addClassMapping(FSTClazzNameRegistry.java:97)
    at org.nustaq.serialization.FSTClazzNameRegistry.registerClassNoLookup(FSTClazzNameRegistry.java:84)
    at org.nustaq.serialization.FSTClazzNameRegistry.registerClass(FSTClazzNameRegistry.java:80)
    at org.nustaq.serialization.FSTConfiguration.addDefaultClazzes(FSTConfiguration.java:811)
    at org.nustaq.serialization.FSTConfiguration.initDefaultFstConfigurationInternal(FSTConfiguration.java:478)
    at org.nustaq.serialization.FSTConfiguration.createDefaultConfiguration(FSTConfiguration.java:473)
    at org.nustaq.serialization.FSTConfiguration.createDefaultConfiguration(FSTConfiguration.java:465)
    at org.redisson.codec.FstCodec.<init>(FstCodec.java:47)
    at org.redisson.config.Config.<init>(Config.java:104)
    at org.redisson.Redisson.<init>(Redisson.java:119)
    at org.redisson.Redisson.create(Redisson.java:164)
    at org.redisson.jcache.JCacheManager.createCache(JCacheManager.java:125)
    at io.pacaso.insights.api.config.Bucket4JConfig.proxyManager(Bucket4JConfig.java:50)

任何帮助将不胜感激。谢谢!

java spring-boot redis redisson bucket4j
1个回答
0
投票

每@tangy(来自评论):

该问题与您的 java 环境无法访问有关 由于 JDK17 中的更新而指定的模块。你需要添加 --add-opens=java.base/java.lang=ALL-UNNAMED 根据您的具体设置添加到您的环境参数中。

© www.soinside.com 2019 - 2024. All rights reserved.