TheElectronWill / night-config

Powerful java configuration library for toml, yaml, hocon, json and in-memory configurations. Serialization/deserialization framework.
GNU Lesser General Public License v3.0
242 stars 28 forks source link

How can Java Maps being Serialized/Deserialized Directly? #170

Closed KrLite closed 6 months ago

KrLite commented 6 months ago

I've noticed that Night Config treats map-like key value pairs as subconfigs. But, what if I need to serialize/deserialize these pairs directly into/from a Java Map (more specifically, HashMap)?

For example, in Java I have:

public class MyConfig {
    public HashMap<String, Integer> exampleMap = new HashMap<>(Map.of("case 1", 1));
}

and I want to have the map in, for instance, toml:

exampleMap = {
  "case 1" = 1
}

If I run the code above directly, an error is thrown:

Unable to make field private static final long java.util.HashMap.serialVersionUID accessible: module java.base does not "opens java.util" to unnamed module @128d2484

And it traces back to line 154 in ObjectConverter.java:

https://github.com/TheElectronWill/night-config/blob/a3c43060f40aa4143c3bfabb5c825083c8c5014d/core/src/main/java/com/electronwill/nightconfig/core/conversion/ObjectConverter.java#L153-L155

I don't know why this would happen (I'm using Oracle OpenJDK version 21.0.1 by the way).

If custom classes (subconfigs) are used, then the advantages of length-variable maps are gone.

Is there any solutions for this? Or is I'm making mistakes serializing/deserializing Java Maps? I'm looking forward to a reply.

KrLite commented 6 months ago

I believe that the operator should be || instead of && to bypass static fields. Otherwise it makes bad accesses to non accessible fields.

截屏2024-05-03 上午11 00 42
KrLite commented 6 months ago

Or it should be object != null instead of object == null, it's a severe bug.

KrLite commented 6 months ago

Well, this bug seems to be fixed in commit https://github.com/TheElectronWill/night-config/commit/0de40dbe32e412dfaf0d8def5e1cae235b103297. However, this is currently only available in snapshots, not releases.

KrLite commented 6 months ago

@TheElectronWill Will snapshot versions be uploaded to sonatype in the future? Currently, it seems that the only way to get a snapshot is to build on jitpack. The bug is really severe, thus the jar released 8 months ago isn't really useable.

Edit: no build artifacts found in jitpack builds.

KrLite commented 6 months ago

Although using mixin fixes the problem of accessing static fields, but it still crashes:

Unable to make field int java.util.HashMap.threshold accessible: module java.base does not "opens java.util" to unnamed module @128d2484

I couldn't find a solution now.

KrLite commented 6 months ago

Night config doesn't support writing maps, is that intended?

I'm trying to use convertion tables to post-process the maps into subconfigs that are writable. However, I strongly suggest implementing the ability to write maps for the writers.

KrLite commented 6 months ago

I have started to reimplement a new ObjectConverter. During implementation, I've learnt that Maps are not easy to serialize/deserialize as most config formats only support String-keyed Maps. And the first most problems I encountered are solved too, one is the incorrect null judgement which is fixed in recent commits, another is the use of ConfigSpec. Although I'm not mastering specs for now, but not using specs for configs prevents many problems to occur. I believe it should be used in a more practical way that causes less issues.

Now my questions are solved. Night config is indeed a nice config library to work with, despite still having some possible advances.

TheElectronWill commented 6 months ago

Hello, This is a legitimate question, though not so easy to implement, as you've found on your own. However, I have good news! It is fixed by #163, and will part of the next release :)