hazelcast抛出java.lang.classnotfoundexception和本地NotFoundException

jslywgbw  于 2021-07-23  发布在  Java
关注(0)|答案(2)|浏览(803)

我想将我的spring boot应用程序升级到java11和tomcat9,它使用hazelcast3.12.9作为兑现机制。当我在本地部署时,一切看起来都很好,缓存也很成功。但是当应用程序在集群上运行时,我从所有3个可用节点接收到以下错误:

  1. com.hazelcast.nio.serialization.HazelcastSerializationException: java.lang.ClassNotFoundException: com.some.service.some.server.domain.ClassA
  2. at com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:88)
  3. at com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:77)
  4. at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:48)
  5. at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:187)
  6. at com.hazelcast.map.impl.proxy.MapProxySupport.toObject(MapProxySupport.java:1237)
  7. at com.hazelcast.map.impl.proxy.MapProxyImpl.get(MapProxyImpl.java:120)
  8. at com.hazelcast.spring.cache.HazelcastCache.lookup(HazelcastCache.java:162)
  9. at com.hazelcast.spring.cache.HazelcastCache.get(HazelcastCache.java:67)
  10. at com.some.service.some.server.domain.ClassACache.get(GlassACache.java:28)
  11. at com.some.service.some.server.domain.ClassAFacade.getClassA(ClassAFacade.java:203)
  12. at com.some.service.some.server.domain.ClassAFacade.getGlassA(ClassAFacade.java:185)
  13. at com.some.service.some.server.domain.ClassALogic.lambda$getClassAInParallel$1(ClassALogic.java:196)
  14. at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
  15. at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
  16. at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
  17. at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
  18. at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:952)
  19. at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:926)
  20. at java.base/java.util.stream.AbstractTask.compute(AbstractTask.java:327)
  21. at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
  22. at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
  23. at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
  24. at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
  25. at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
  26. at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
  27. Caused by: java.lang.ClassNotFoundException: com.some.service.some.server.domain.ClassA
  28. at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
  29. at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
  30. at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
  31. at com.hazelcast.nio.ClassLoaderUtil.tryLoadClass(ClassLoaderUtil.java:288)

hazelcast定制器:

  1. @Configuration
  2. public class ClassAHazelcastConfig {
  3. private static final MaxSizePolicy HAZELCAST_DEFAULT_MAX_SIZE_POLICY = MaxSizePolicy.PER_NODE;
  4. private static final EvictionPolicy HAZELCAST_DEFAULT_EVICTION_POLICY = EvictionPolicy.LRU;
  5. @Bean
  6. HazelcastConfigurationCustomizer customizer(CachePropertiesHolder cacheProperties) {
  7. return config -> {
  8. config.addMapConfig(new MapConfig()
  9. .setName(CLASS_A_CACHE)
  10. .setMaxSizeConfig(new MaxSizeConfig(cacheProperties.getMaxsize(), HAZELCAST_DEFAULT_MAX_SIZE_POLICY))
  11. .setEvictionPolicy(HAZELCAST_DEFAULT_EVICTION_POLICY)
  12. .setTimeToLiveSeconds(cacheProperties.getTtl()));
  13. config.getSerializationConfig().addSerializerConfig(
  14. new SerializerConfig()
  15. .setImplementation(new OptionalStreamSerializer())
  16. .setTypeClass(Optional.class)
  17. );
  18. };
  19. }
  20. }
  1. @Configuration
  2. @EnableConfigurationProperties(CachePropertiesHolder.class)
  3. public class CacheConfig implements CachingConfigurer, EnvironmentAware, ApplicationContextAware {
  4. public static final String CLASS_A_CACHE = "CACHE_A";
  5. private Environment environment;
  6. private ApplicationContext applicationContext;
  7. @Override
  8. @Bean(name="cacheManager")
  9. public CacheManager cacheManager() {
  10. boolean cachingEnabled = Boolean.parseBoolean(environment.getProperty("cache.enabled"));
  11. if (cachingEnabled) {
  12. HazelcastInstance instance = (HazelcastInstance) applicationContext.getBean("hazelcastInstance");
  13. return new HazelcastCacheManager(instance);
  14. }
  15. return new NoOpCacheManager();
  16. }
  17. @Override
  18. public CacheResolver cacheResolver() {
  19. return new SimpleCacheResolver(Objects.requireNonNull(cacheManager()));
  20. }
  21. @Bean
  22. @Override
  23. public KeyGenerator keyGenerator() {
  24. return new SimpleKeyGenerator();
  25. }
  26. @Bean
  27. @Override
  28. public CacheErrorHandler errorHandler() {
  29. return new SimpleCacheErrorHandler();
  30. }
  31. @Override
  32. public void setEnvironment(@NotNull Environment environment) {
  33. this.environment = environment;
  34. }
  35. @Override
  36. public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
  37. this.applicationContext = applicationContext;
  38. }
  39. }

使用Java8和Tomcat8,一切都正常工作。
更新:
经过几天的调查,我发现这些异常被抛出到所使用的并行流中的唯一位置。

  1. return forkJoinPool.submit(() ->
  2. items.parallelStream()
  3. .map(item -> {
  4. try {
  5. return biFunction.apply(item);
  6. } catch (Exception e) {
  7. LOG.error("Error", e);
  8. return Optional.<Item>empty();
  9. }
  10. })

奇怪的是,对于Java8和Tomcat8,我没有这个问题。

smtd7mpg

smtd7mpg1#

hazelcast提供了两种部署模式:嵌入式模式和客户机-服务器模式。有关更多信息,请查看相关文档部分。
在前一种情况下,只有一个jvm,所有类都在类路径上。
在后一种情况下,您至少有2个JVM,每个客户机一个,成员一个。似乎您忘记设置要引用的成员的类路径 ClassA .
如何设置类路径取决于如何启动hazelcast成员。在大多数情况下有效的方法是使用 CLASSPATH 环境变量。

yacmzcpb

yacmzcpb2#

最终,它与黑兹卡斯特完全无关。主要是Java11与Java8的不同。
在抛出异常的部分,使用了一个来自Java11的forkjoinpool,它不能保证何时创建,而且它似乎没有与spring应用程序相同的类加载器(在java 11的spring boot项目中,具有默认访问权限的类在运行时会导致noclassdeffound错误)
我做了一个错误的假设,因为例外来自hazelcast,我也看到了其他相关的问题。

相关问题