gradle 无法获取对“jdk.internal.misc.Unsafe”的访问权限

6gpjuf90  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(448)

我正在Micronaut应用程序(JDK 17)中使用Microstream执行我的第一步。
我已经实现了以下存储库

@Singleton
@RequiredArgsConstructor
public class DefaultWritableProductRepository implements WritableProductRepository {

  private final StorageManager storageManager;

  @Override
  public Product save(Product product) { // Product is an interface

    data().getProducts().put(product.id(), product);
    storageManager.store(data().getProducts());
    return product;
  }

  private RootData data() {
    return (RootData) storageManager.root();
  }
}

和我的数据根来存储数据。

@Introspected
public class RootData {

  private Map<UUID, Product> products = new HashMap<>();

  @NotNull
  public Map<UUID, Product> getProducts() {
    return products;
  }
}

当我存储一个产品时,我得到一个IllegalAccessException,因为Microstream想要访问jdk.internal.misc,但这当然是默认情况下不允许的。

15:36:20.222 [MicroStream-StorageChannel-0] DEBUG o.m.s.t.StorageEntityCache$Default - Consolidated StorageEntityCache to 1 entries!
Exception in thread "main" java.lang.Error: Could not obtain access to "jdk.internal.misc.Unsafe", please start the VM with --add-exports java.base/jdk.internal.misc=ALL-UNNAMED
    at one.microstream.memory.sun.JdkInternals.createInternalVM(JdkInternals.java:920)
    at one.microstream.memory.sun.JdkInternals.internalVM(JdkInternals.java:896)
    at one.microstream.memory.sun.JdkInternals.lookupInternalObjectFieldOffsetMethod(JdkInternals.java:948)
    at one.microstream.memory.sun.JdkInternals.internalObjectFieldOffsetMethod(JdkInternals.java:937)
    at one.microstream.memory.sun.JdkInternals.objectFieldOffset(JdkInternals.java:975)
    at one.microstream.memory.sun.JdkInternals.objectFieldOffsets(JdkInternals.java:1002)
    at one.microstream.memory.sun.JdkMemoryAccessor.objectFieldOffsets(JdkMemoryAccessor.java:540)
    at one.microstream.memory.sun.JdkMemoryAccessor.objectFieldOffsets(JdkMemoryAccessor.java:554)
    at one.microstream.memory.XMemory.objectFieldOffsets(XMemory.java:652)
    at one.microstream.persistence.binary.internal.AbstractBinaryHandlerReflective.objectFieldOffsets(AbstractBinaryHandlerReflective.java:183)
    at one.microstream.persistence.binary.internal.AbstractBinaryHandlerReflective.initializeStoringMemoryOffsets(AbstractBinaryHandlerReflective.java:335)
    at one.microstream.persistence.binary.internal.AbstractBinaryHandlerReflective.<init>(AbstractBinaryHandlerReflective.java:298)
    at one.microstream.persistence.binary.internal.BinaryHandlerGenericType.<init>(BinaryHandlerGenericType.java:84)
    at one.microstream.persistence.binary.internal.BinaryHandlerGenericType.New(BinaryHandlerGenericType.java:47)
    at one.microstream.persistence.binary.types.BinaryTypeHandlerCreator$Default.internalCreateTypeHandlerGeneric(BinaryTypeHandlerCreator.java:257)
    at one.microstream.persistence.types.PersistenceTypeHandlerCreator$Abstract.createTypeHandlerGeneric(PersistenceTypeHandlerCreator.java:185)
    at one.microstream.persistence.types.PersistenceTypeHandlerEnsurer$Default.ensureTypeHandler(PersistenceTypeHandlerEnsurer.java:257)
    at one.microstream.persistence.internal.PersistenceTypeHandlerProviderCreating.ensureTypeHandler(PersistenceTypeHandlerProviderCreating.java:191)
    at one.microstream.persistence.internal.PersistenceTypeHandlerProviderCreating.provideTypeHandler(PersistenceTypeHandlerProviderCreating.java:99)
    at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.internalEnsureTypeHandler(PersistenceTypeHandlerManager.java:615)
    at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.ensureTypeHandler(PersistenceTypeHandlerManager.java:384)
    at one.microstream.persistence.types.PersistenceTypeHandlerManager$Default.ensureTypeHandler(PersistenceTypeHandlerManager.java:360)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.registerGuaranteed(BinaryStorer.java:618)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.registerLazyOptional(BinaryStorer.java:633)
    at one.microstream.persistence.types.PersistenceObjectManager$Default.ensureObjectId(PersistenceObjectManager.java:202)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.register(BinaryStorer.java:652)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.apply(BinaryStorer.java:328)
    at one.microstream.persistence.binary.types.Binary.storeMapEntrySet(Binary.java:536)
    at one.microstream.persistence.binary.jdk8.java.util.BinaryHandlerHashMap.store(BinaryHandlerHashMap.java:105)
    at one.microstream.persistence.binary.jdk8.java.util.BinaryHandlerHashMap.store(BinaryHandlerHashMap.java:1)
    at one.microstream.persistence.binary.internal.AbstractBinaryHandlerCustom.store(AbstractBinaryHandlerCustom.java:1)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.storeItem(BinaryStorer.java:459)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.storeGraph(BinaryStorer.java:442)
    at one.microstream.persistence.binary.types.BinaryStorer$Default.store(BinaryStorer.java:466)
    at one.microstream.persistence.types.PersistenceManager$Default.store(PersistenceManager.java:304)
    at one.microstream.storage.types.StorageConnection.store(StorageConnection.java:381)
    at ch.onstructive.salessystem.productengine.db.loader.DefaultWritableProductRepository.save(DefaultWritableProductRepository.java:32)
    at ch.onstructive.salessystem.productengine.db.loader.datatransformers.AbstractDataTransformer.persist(AbstractDataTransformer.java:98)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1921)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
    at ch.onstructive.salessystem.productengine.db.loader.datatransformers.AbstractDataTransformer.transformAndPersist(AbstractDataTransformer.java:85)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at ch.onstructive.salessystem.productengine.db.loader.ProductLoaderCommand.run(ProductLoaderCommand.java:58)
    at picocli.CommandLine.executeUserObject(CommandLine.java:1939)
    at picocli.CommandLine.access$1300(CommandLine.java:145)
    at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358)
    at picocli.CommandLine$RunLast.handle(CommandLine.java:2352)
    at picocli.CommandLine$RunLast.handle(CommandLine.java:2314)
    at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
    at picocli.CommandLine$RunLast.execute(CommandLine.java:2316)
    at picocli.CommandLine.execute(CommandLine.java:2078)
    at io.micronaut.configuration.picocli.PicocliRunner.run(PicocliRunner.java:137)
    at io.micronaut.configuration.picocli.PicocliRunner.run(PicocliRunner.java:114)
    at ch.onstructive.salessystem.productengine.db.loader.ProductLoaderCommand.main(ProductLoaderCommand.java:50)
Caused by: java.lang.IllegalAccessException: class one.microstream.memory.sun.JdkInternals cannot access class jdk.internal.misc.Unsafe (in module java.base) because module java.base does not export jdk.internal.misc to unnamed module @355ce81c
    at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:420)
    at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:709)
    at java.base/java.lang.reflect.Method.invoke(Method.java:569)
    at one.microstream.memory.sun.JdkInternals.createInternalVM(JdkInternals.java:909)
    ... 61 more

当我启动Micronaut应用程序并添加VM选项--add-exports java.base/jdk.internal.misc=ALL-UNNAMED时,一切正常。
如上面的清单所述,类型Product是一个接口,这个数据结构中的某些内容触发了错误,Product的实际实现是一个名为DefaultProduct的Java记录。

@Introspected
public record DefaultProduct(
    @NotNull UUID id,
    @NotNull LocalDate validFrom,
    @NotNull LocalDate validUntil,
    @NotNull @NotBlank String name,
    @NotNull @NotEmpty List<PriceElement> priceElements,
    @NotNull @NotEmpty Set<Criterion> criteria,
    @NotNull LegalBasis legalBasis)
    implements Product {}

我已经将RootData中的map从Map<UUID, Product>替换为Map<UUID, String>,不使用--add-exports java.base/jdk.internal.misc=ALL-UNNAMED问题就消失了,所以这显然与我的数据结构Product有关。
问题是我无法使用Gradle运行测试,即使我告诉JVM添加该选项。

tasks.named('test') {
    jvmArgs ['--add-exports java.base/jdk.internal.misc=ALL-UNNAMED']
}

所以我有以下几个问题:
1.有没有人知道为什么微流需要访问它,并给我指出可能出错的方向?
1.是否有办法在Gradle构建版本中运行我的测试并添加VM选项,以便可以执行测试并解决问题?

tez616oj

tez616oj1#

原来这与Java记录有关。当将Java记录转换为POJO时,不会引发错误。

@Introspected
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DefaultProduct implements Product {
  private @NotNull UUID id;
  private @NotNull LocalDate validFrom;
  private @NotNull LocalDate validUntil;
  private @NotNull @NotBlank String name;
  private @NotNull @NotEmpty List<PriceElement> priceElements;
  private @NotNull @NotEmpty Set<Criterion> criteria;
  private @NotNull LegalBasis legalBasis;
}

错误原因在Microstream FAQ中说明。
MicroStream可以处理记录吗?可以,但由于Java 15中引入的记录反射限制,必须将导出添加到VM参数中:--添加导出java.base/jdk.internal.misc=全部未命名

相关问题