Deserializing Singleton - java

//Singleton
public class MainList implements Serializable {
private static MainList instance = new MainList();
private MainList() {}
public static MainList getInstance() {
return instance;
}
}
//Trying to deserialize..
public MainWindow() {
//Importing the latest version if it exists in path
MainList mainListObj = MainList.getInstance();
try {
FileInputStream fis = new FileInputStream(path);
ObjectInputStream oin = new ObjectInputStream(fis);
mainListObj = (MainList) oin.readObject(); //HERE//////
}
catch (Exception exc) {
return;
}
}
Singleton-Object of class MainList is serialized & can be found by path.
On the line //HERE/// object successfully deserializing to mainListObj,
BUT it's local..
How can I make it global? I think it could be solved by chanching getInstance method..somehow..

Your case is not singleton.
In your case, you can simply provide a setter.
static void setInstance(MainList newInstance) {
instance = newInstance;
}
MainList.setInstance(mainListObj);

Related

How to write this Java Class in C# Class format

How to write this Java Class in C# Class format
public final class JsonParserResolver {
// PlacesApiJsonParser is an Interface
public static final PlacesApiJsonParser JSON_PARSER;
static {
boolean hasGson;
try {
Class.forName("com.google.gson.Gson");
hasGson = true;
} catch (ClassNotFoundException e) {
hasGson = false;
}
JSON_PARSER = hasGson ? new GsonPlacesApiJsonParser() : new
AndroidPlacesApiJsonParser();
}
private JsonParserResolver() {
throw new RuntimeException("No instances");
}
}
The class static member is resolving stuff automatically on Class instantiation. This is a very useful
Hold your horses this is where I am, I get a little stuck on the JSON_PARSER
namespace WorkSampleBookSearch
{
public final class JsonParserResolver
{
public static final PlacesApiJsonParser JSON_PARSER;
static {
boolean hasGson;
JSON_PARSER = hasGson? new GsonPlacesApiJsonParser() : new AndroidPlacesApiJsonParser();
}
private JsonParserResolver()
{
throw new RuntimeException("No instances");
}
}
}

Instanceof returns false for same class after serialization

Instanceof returns false for same class after org.springframework.security.oauth2.common.util.SerializationUtils fasterxml deserialization in Spring boot application
new ObjectMapper().readValue(serialized, User.class);
Class
public class User implements Serializable {//...
}
Because new object getClass().getClassloader() returns different classloader, how to fix this and casting issue?
In this case you should compare the class names rather then using instanceof. Even if the classes are loaded by different class loaders the canonical names will be the same:
public boolean haveSameCanonicalName(Object object, Class<?> clazz) {
String actualClassName = object.getClass().getCanonicalName();
String expectedClassName = clazz.getCanonicalName();
return actualClassName.equals(expectedClassName);
}
And then you can use it like this:
if (haveSameCanonicalName(user, User.class)) {
// Do something here
}
UPDATE:
If you still need to cast the object there is a workaround:
public class CrossCastUtils {
private final ObjectOutputStream oos;
private final ObjectInputStream ois;
public CrossCastUtils() throws IOException {
final PipedOutputStream pos = new PipedOutputStream();
final PipedInputStream pis = new PipedInputStream(pos);
oos = new ObjectOutputStream(pos);
ois = new ObjectInputStream(pis);
}
public <T> T cast(Object object) throws IOException, ClassNotFoundException {
oos.writeObject(object);
oos.flush();
return (T) ois.readObject();
}
Try to run this test:
#Test
public void testCrossCast(){
Object initial = ... // retrieve it as you did before
User result = CrossCastUtils.cast(initial);
assertFalse(initial instanceof User);
assertTrue(result instanceof User);
}

Loading serialized object

I am beginning java, and started to play with serialization. I wonder if there is any way to write the deserialization function inside the class itself. Let me clarify what I mean: I can deserialize an object (i.e. from class Person) from within another class and it works:
public class Dummy{
...
public static void main(String args[])
{
...
Person father = null;
try {
FileInputStream load = new FileInputStream(saved_file);
ObjectInputStream in = new ObjectInputStream(load);
indiv = (Person) in.readObject();
in.close();
load.close();
} catch (...) { ... }
}
}
But, for being tidy, is it possible to move this inside the Person class as a function? For instance, to do something like this:
public class Person implements Serializable {
private boolean isOrphan = false;
private Person parent;
...
public void load(File saved_file) {
try {
FileInputStream load = new FileInputStream(saved_file);
ObjectInputStream in = new ObjectInputStream(load);
this = (Person) in.readObject(); // Error: cannot assign a value to final variabl this
in.close();
load.close();
} catch (...) { ... }
}
}
And then in the other class just call this:
public class Dummy{
...
public static void main(String args[])
{
...
Person father = null;
father.load(saved_file);
}
}
You can't call an instance method on an instance that doesn't exist yet. Even if your code could compile, you would get a NullPointerException because youĆ¹re calling a method on null.
Make your method static and make it return the deserialized instance. More generally, this is not a variable that you can assign, it's an immutable reference to an object.
public static Person load(File saved_file) {
try (FileInputStream load = new FileInputStream(saved_file);
ObjectInputStream in = new ObjectInputStream(load)) {
return (Person) in.readObject();
} catch (...) { ... }
}
public class Dummy {
public static void main(String args[]) {
Person father = Person.load(saved_file);
}
}
PS: I also added try-catch with resources instead of explicit close() because it's safer.

Create instance of a variable in another class

i have this code:
File fileData = new File(this.getDataFolder(), "data.yml");
FileConfiguration data = YamlConfiguration.loadConfiguration(fileData);
data.options().copyDefaults(true);
try {
data.save(fileData);
} catch (IOException e) {
e.printStackTrace();
}
now my question is how i can do a instance of data in other class, i mean this is bukkit so i need that in another class i can execute the command data.save(fileData);
If you need that specific instance of FileConfiguration, the only way to have its reference in another class is using constructors, assuming the other class where you need this object is created in this class you could do something like so:
class YourClass{
File fileData;
FileConfiguration data;
#Override
void onEnable(){
fileData = new File(this.getDataFolder(), "data.yml");
data = YamlConfiguration.loadConfiguration(fileData);
data.options().copyDefaults(true);
try {
data.save(fileData);
} catch (IOException e) {
e.printStackTrace();
}
}
void theMethodWhereYouInstantiateTheOtherClass(){
OtherClass oc = new OtherClass();
}
}
And the the other class would look something like:
class OtherClass{
FileConfiguration data;
public OtherClass(FileConfiguration data){
this.data = data;
}
}

How to call parent class objects within a subclass?

I'm not sure if I'm asking this right, as I'm attempting to teach myself Java. I have a class which contains my main method, and within this class are several subclasses that need access to my user settings using java.util.Properties. I have to create the properties object in every subclass in order to make it work, and I can't reference the object using configFilePath, it must be null. I'm wondering if I can create this public object within the parent class, so I don't need to create it in all of its subclasses? Here is my code, I'm really not sure I'm doing this right although it works.
public class Frame1 extends JFrame {
Settings config = new Settings(); //this is the object I want to reference within subclasses
class Update extends SwingWorker<Integer, Void> { //first subclass
#Override
protected Integer doInBackground() throws Exception {
Settings config = new Settings(configFilePath); //yet I have to create the object within every subclass, this time an argument is required.
String templateDir = config.getProperty("templatedir");
String writePath = config.getProperty("outputdir");
//do some logic code, not required for my question
}
#Override
protected void done() {
Update2 update2 = new Update2();
update2.execute(); //start the next subclass which also needs access to Settings(configFilePath)
}
}
}
public class Settings extends JFrame {
String configFilePath = "C:/path/to/settings.properties";
Properties properties = new Properties();
public Settings(String configFilePath) throws IOException {
this.configFilePath = configFilePath;
FileInputStream fis = null;
try {
fis = new FileInputStream(configFilePath);
properties.load(fis);
} catch (FileNotFoundException e) {
setDefaults();
} finally {
if (fis != null) {
fis.close();
}
}
}
}
I'm not sure if I'm doing this right or not, it seems to work but seems to be rather redundant having to create the config object every time I need to access my user settings. I hope this hasn't been asked before, and if it has please link me, as I could not find it.
You can create the Setting class as a Singleton pattern, here is one example:
public class Settings extends JFrame{
String configFilePath = "C:/path/to/settings.properties";
Properties properties = new Properties();
private static Settings instance;
public static Settings getInstance(){
if(instance==null){
instance = new Setting();
}
return instance;
}
private Settings() throws IOException {
FileInputStream fis = null;
try {
fis = new FileInputStream(configFilePath);
properties.load(fis);
} catch (FileNotFoundException e) {
setDefaults();
} finally {
if (fis != null) {
fis.close();
}
}
}
}
Usage in any other class of your system:
Settings.getInstance().getProperty("...");
From Update you can use Frame1.this to access the this of Frame1 (because Update is an inner class of Frame1).
Then to access config you can use Frame1.this.config.
Here is a working example:
public class PrefixerFactory {
private String prefix; // Used by Prefixer
public PrefixerFactory(String prefix) {
this.prefix = prefix;
}
public Prefixer createPrefixer() {
return new Prefixer();
}
public class Prefixer { // Inner class
public String addPrefix(String value) {
// Using "prefix" from PrefixerFactory
return PrefixerFactory.this.prefix + value;
}
}
public static void main(String[] args) {
Prefixer helloPrefixer = new PrefixerFactory("Hello ").createPrefixer();
Prefixer goodbyePrefixer = new PrefixerFactory("Good bye ").createPrefixer();
System.out.println(helloPrefixer.addPrefix("world")); // Hello world
System.out.println(goodbyePrefixer.addPrefix("world")); // Good bye world
}
}

Categories