我正在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选项,以便可以执行测试并解决问题?
1条答案
按热度按时间tez616oj1#
原来这与Java记录有关。当将Java记录转换为POJO时,不会引发错误。
错误原因在Microstream FAQ中说明。
MicroStream可以处理记录吗?可以,但由于Java 15中引入的记录反射限制,必须将导出添加到VM参数中:--添加导出java.base/jdk.internal.misc=全部未命名