Original issue: The program was reading the inputs of the old config file (.ini)
New issue: After attempting a singleton pattern with the stream/ini, I am unable to write to file anymore. Its throwing a java.io.FileNotFoundException.
Is there anyway I can modify my Configuration class to make it work?
Thanks in advance.
Configuration class:
import org.ini4j.Wini;
import java.io.*;
//http://www.javenue.info/post/40
public class Configuration {
private static Configuration _instance = null;
private Wini ini = null;
FileInputStream stream;
private Configuration() {
ini= new Wini();
try {
stream = new FileInputStream(Constants.PATH);
ini.load(stream);
}
catch (Exception e) {
System.out.println("FILE NOT FOUND!");
}
}
public synchronized static Configuration getInstance() {
if (_instance == null)
_instance = new Configuration();
return _instance;
}
public String getConfig(String xSectionName, String xFieldValue){
String readValue = null;
if (ini.get(xSectionName, xFieldValue) != null) {
readValue = ini.get(xSectionName, xFieldValue);
} else {
// TODO: What should happen
}
return readValue;
}
public void setConfig(String xSectionName, String xFieldValue, String xValue){
System.out.println("Section: " + xSectionName);
System.out.println("Field: " + xFieldValue);
System.out.println("Value: " + xValue + "\n\n");
try {
ini.put(xSectionName, xFieldValue, xValue);
ini.store();
} catch (Exception e1) {
System.out.println(xValue + " could not be stored.");
e1.printStackTrace();
}
}
}
Section: drift
Field: mu
Value: 5
5 could not be stored.
java.io.FileNotFoundException at org.ini4j.Ini.store(Ini.java:126) at application.prototypes.Configuration.setConfig(Configuration.java:72) at application.prototypes.UserInputs.lambda$0(UserInputs.java:92) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.event.Event.fireEvent(Event.java:198) at javafx.scene.Scene$KeyHandler.process(Scene.java:3964) at javafx.scene.Scene$KeyHandler.access$1800(Scene.java:3910) at javafx.scene.Scene.impl_processKeyEvent(Scene.java:2040) at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2501) at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:216) at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:148) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$353(GlassViewEventHandler.java:247) at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:246) at com.sun.glass.ui.View.handleKeyEvent(View.java:546) at com.sun.glass.ui.View.notifyKey(View.java:966) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) at java.lang.Thread.run(Unknown Source)
Resolution to New Issue: See answer below.
Resolution to Original Issue:
I was dynamically loading a class with the Java-Runtime-Compiler library. After some research, I read that a ClassLoader can only have one instance of a particular class. So, the solution is to create a new instance of a ClassLoader in the .loadFromJava() method and boom problem solved.
Here is a bit of code.
import net.openhft.compiler.CompilerUtils;
...
ClassLoader classloader = new ClassLoader() {
};
Class aClass = CompilerUtils.CACHED_COMPILER.loadFromJava(classloader, className, javaCode);
Callable<Object[]> caller = (Callable<Object[]>) aClass.newInstance();
Object[] obj = (Object[]) caller.call();
...
The dynamic class implements Callable and returns the object - so one can retrieve whatever its created in there.
I have just looked in the source code.
The problem is that
void load(InputStream input)
inWini
class should be avoided to load the ini file if you want to use the sameWini
instance to invoke thestore()
method.Why ? Because the
store()
method expects to have a existing file field in the instance of the currentWini
but it cannot find it as you have loaded the ini from a stream and not a file.So you should load the ini file by using the
Wini
constructor. The constructor taking as parameter aFile
and it also sets the field inside the instance additionally to load the ini content.Look at this :
So replace :
by this :
Here is the full class using logging to log exception and which use a lazy singleton implementation without using any explicit synchronization as
synchronized
: