(Possibly solved) Automatic Config Saver parameterized gson cast problem

I have the problem that once I restart MC it can no longer be casted. After indexing its the type Linkedtreemap even though the object is in a List of the type TrustedPartyMember. I had a look around however I was not able to come up with a solution. Object is created with new row in trustedpartmemberconfig screen using addrow method in there. Saving is with Configmanager .save. Affected List is List<TrustedPartyMember> in Party Config It works on init but fails casting after loading using gson later. code is attached in the Messages below. The Full Code is also available throught the following links. Full Code links: TrustedPartyMember.java https://github.com/HacktheTime/BBsentials/blob/hypeswap/common/src/main/java/de/hype/bbsentials/client/common/client/objects/TrustedPartyMember.java SelectionScreen<T>.java https://github.com/HacktheTime/BBsentials/blob/hypeswap/fabric/src/main/java/de/hype/bbsentials/fabric/screens/SelectionScreen.java TrustedPartyMemberConfigScreen.java https://github.com/HacktheTime/BBsentials/blob/hypeswap/fabric/src/main/java/de/hype/bbsentials/fabric/screens/TrustedPartyMembersConfigScreen.java ConfigManager.java https://github.com/HacktheTime/BBsentials/blob/hypeswap/common/src/main/java/de/hype/bbsentials/client/common/config/ConfigManager.java PartyConfig https://github.com/HacktheTime/BBsentials/blob/hypeswap/common/src/main/java/de/hype/bbsentials/client/common/config/PartyConfig.java
11 Replies
JavaBot
JavaBot9mo ago
This post has been reserved for your question.
Hey @Hype_the_Time! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
Hype_the_Time
Hype_the_TimeOP9mo ago
Config Manager
package de.hype.bbsentials.client.common.config;

import java.util.ArrayList;
import java.util.List;

public class ConfigManager {
private static final List<BBsentialsConfig> registeredConfigs = new ArrayList<>();

public static void registerConfig(BBsentialsConfig config) {
registeredConfigs.add(config);
}

public static void reloadAllConfigs() {
for (BBsentialsConfig config : registeredConfigs) {
config.loadConfiguration();
}
}

public static List<Class<? extends BBsentialsConfig>> getLoadedConfigClasses() {
List<Class<? extends BBsentialsConfig>> configClasses = new ArrayList<>();
for (BBsentialsConfig config : registeredConfigs) {
configClasses.add(config.getClass());
}
return configClasses;
}

public static void saveAll() {
for (BBsentialsConfig config : registeredConfigs) {
config.save();
}
}

public static List<BBsentialsConfig> getAllConfigs() {
return new ArrayList<>(registeredConfigs);
}
}
package de.hype.bbsentials.client.common.config;

import java.util.ArrayList;
import java.util.List;

public class ConfigManager {
private static final List<BBsentialsConfig> registeredConfigs = new ArrayList<>();

public static void registerConfig(BBsentialsConfig config) {
registeredConfigs.add(config);
}

public static void reloadAllConfigs() {
for (BBsentialsConfig config : registeredConfigs) {
config.loadConfiguration();
}
}

public static List<Class<? extends BBsentialsConfig>> getLoadedConfigClasses() {
List<Class<? extends BBsentialsConfig>> configClasses = new ArrayList<>();
for (BBsentialsConfig config : registeredConfigs) {
configClasses.add(config.getClass());
}
return configClasses;
}

public static void saveAll() {
for (BBsentialsConfig config : registeredConfigs) {
config.save();
}
}

public static List<BBsentialsConfig> getAllConfigs() {
return new ArrayList<>(registeredConfigs);
}
}
Party Config Simplified
package de.hype.bbsentials.client.common.config;

import de.hype.bbsentials.client.common.client.objects.TrustedPartyMember;

import java.util.List;


public class PartyConfig extends BBsentialsConfig {
public transient List<TrustedPartyMember> recommendedTrustedMembers;

public PartyConfig() {
super(1);
doInit();
}

@Override
public void onInit() {

}

}
package de.hype.bbsentials.client.common.config;

import de.hype.bbsentials.client.common.client.objects.TrustedPartyMember;

import java.util.List;


public class PartyConfig extends BBsentialsConfig {
public transient List<TrustedPartyMember> recommendedTrustedMembers;

public PartyConfig() {
super(1);
doInit();
}

@Override
public void onInit() {

}

}
config load code:
protected void loadConfiguration() {
Field[] fields = this.getClass().getDeclaredFields();

for (Field field : fields) {
if (!java.lang.reflect.Modifier.isTransient(field.getModifiers())) {
try {
field.setAccessible(true);
String fieldName = field.getName();
JsonObject jsonObject = loadJsonFile();
if (jsonObject.has(fieldName)) {
field.set(this, CustomGson.create().fromJson(jsonObject.get(fieldName), field.getType()));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
protected void loadConfiguration() {
Field[] fields = this.getClass().getDeclaredFields();

for (Field field : fields) {
if (!java.lang.reflect.Modifier.isTransient(field.getModifiers())) {
try {
field.setAccessible(true);
String fieldName = field.getName();
JsonObject jsonObject = loadJsonFile();
if (jsonObject.has(fieldName)) {
field.set(this, CustomGson.create().fromJson(jsonObject.get(fieldName), field.getType()));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
save code:
public void save() {
JsonObject jsonObject = new JsonObject();

for (Field field : getClass().getDeclaredFields()) {
if (!java.lang.reflect.Modifier.isTransient(field.getModifiers())) {
try {
field.setAccessible(true);
jsonObject.add(field.getName(), CustomGson.create().toJsonTree(field.get(this)));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

String fileName = getClass().getSimpleName() + ".json";
File configFile = new File(configFolder, fileName);

try (FileWriter writer = new FileWriter(configFile)) {
Gson gson = CustomGson.create();
String jsonOutput = gson.toJson(jsonObject);
writer.write(jsonOutput);
} catch (Exception e) {
e.printStackTrace();
}
}
public void save() {
JsonObject jsonObject = new JsonObject();

for (Field field : getClass().getDeclaredFields()) {
if (!java.lang.reflect.Modifier.isTransient(field.getModifiers())) {
try {
field.setAccessible(true);
jsonObject.add(field.getName(), CustomGson.create().toJsonTree(field.get(this)));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

String fileName = getClass().getSimpleName() + ".json";
File configFile = new File(configFolder, fileName);

try (FileWriter writer = new FileWriter(configFile)) {
Gson gson = CustomGson.create();
String jsonOutput = gson.toJson(jsonObject);
writer.write(jsonOutput);
} catch (Exception e) {
e.printStackTrace();
}
}
Simp0lefied Screen Code
package de.hype.bbsentials.fabric.screens;

import de.hype.bbsentials.client.common.chat.Chat;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;

import java.util.ArrayList;
import java.util.List;

public abstract class SelectionScreen<T> extends Screen {
Screen parent;
int page = 0;

public SelectionScreen(Screen parent, String displayName) {
super(Text.of(displayName));
if (parent == null) parent = MinecraftClient.getInstance().currentScreen;
this.parent = parent;
}

public abstract List<T> getObjectList();

private List<T> getObjectsInternal() {
return new ArrayList<>(getObjectList());
}

@Override
protected void init() {
//Some Removed code
updateFields();

}

protected abstract void addNewRow();

private void addNewRowPrivate() {
addNewRow();
updateFields();
}

void removeRow(T node) {
try {
getObjectsInternal().remove(node);
} catch (Exception e) {
Chat.sendPrivateMessageToSelfError(e.getMessage());
}
updateFields();
}

public abstract void doOnButtonClick(T object, ButtonWidget buttonWidget);

protected void updateFields() {
//Removed code here
List<T> objects = getObjectsInternal();
List<T> sublist = objects.subList(startPoint, end);
for (int i = 0; i < sublist.size(); i++) {
T object = sublist.get(i);
//This is where the error occurs
}
}

public abstract String getButtonString(T object);

public abstract void done();

@Override
public abstract boolean shouldCloseOnEsc();

@Override
public abstract void close();
}
package de.hype.bbsentials.fabric.screens;

import de.hype.bbsentials.client.common.chat.Chat;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;

import java.util.ArrayList;
import java.util.List;

public abstract class SelectionScreen<T> extends Screen {
Screen parent;
int page = 0;

public SelectionScreen(Screen parent, String displayName) {
super(Text.of(displayName));
if (parent == null) parent = MinecraftClient.getInstance().currentScreen;
this.parent = parent;
}

public abstract List<T> getObjectList();

private List<T> getObjectsInternal() {
return new ArrayList<>(getObjectList());
}

@Override
protected void init() {
//Some Removed code
updateFields();

}

protected abstract void addNewRow();

private void addNewRowPrivate() {
addNewRow();
updateFields();
}

void removeRow(T node) {
try {
getObjectsInternal().remove(node);
} catch (Exception e) {
Chat.sendPrivateMessageToSelfError(e.getMessage());
}
updateFields();
}

public abstract void doOnButtonClick(T object, ButtonWidget buttonWidget);

protected void updateFields() {
//Removed code here
List<T> objects = getObjectsInternal();
List<T> sublist = objects.subList(startPoint, end);
for (int i = 0; i < sublist.size(); i++) {
T object = sublist.get(i);
//This is where the error occurs
}
}

public abstract String getButtonString(T object);

public abstract void done();

@Override
public abstract boolean shouldCloseOnEsc();

@Override
public abstract void close();
}
JavaBot
JavaBot9mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
Hype_the_Time
Hype_the_TimeOP9mo ago
Bump
Kyo-chan
Kyo-chan9mo ago
It would help if you explained why you don't simplify the problem
Hype_the_Time
Hype_the_TimeOP9mo ago
Wdym
Kyo-chan
Kyo-chan9mo ago
- You have some difficulty with Gson - You're showing dozens of files involving Minecraft modding => what happened so that what you're showing isn't a 10-lines max program trying to use Gson?
Hype_the_Time
Hype_the_TimeOP9mo ago
The problem with it is that it is integrated into a more or less automated config. Furthermore from the research I did It seems to be a problem with generalised classes. Due too me extending classes at those positions as well and me not knowing what is the source and may be needed I added those things. Those increase the size heavily I more or less wanted to make sure that all needed info is there
Kyo-chan
Kyo-chan9mo ago
As long as the problem hasn't disappeared, then it is simply factual that all the info is there It sounds like you have not even tried to play with gson first in the simplest possible case, when you noticed that you didn't get what you want Working in the simplest case first is simply what you do before doing anything else would cross your mind, at least if you"re serious about programming
Hype_the_Time
Hype_the_TimeOP9mo ago
I use this config since a while now but i had a different issue somewhere different which caused the problem to only appear now My research told me its a problem with generalization of classes. The suggested fixes where always things that seemed to be for android with automatically picked up .pro files. I was not able to find a solutions outside of android for default java and mc modding. I uses dcs like this as second to last step and try to use other sources. Besides I used it at some different things and server side code too. Both together have right now around 23k lines of code. Not that much but still something. You seem to suggest a simpler test but I still did not get any ideas on how to fix the problem at all. I dont know why but now I first try found a stackoverflow post I did not find before. MyClass object = new Gson().fromJson(new Gson().toJson(((LinkedTreeMap<String, Object>) theLinkedTreeMapObject)), MyClass .class) Could potentially be a solution to the problem dont know whether its the cleanest solution but could very well work. Ill have a try at it later. Knowingly not closing it yet until i got it fixed
JavaBot
JavaBot9mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
Want results from more Discord servers?
Add your server