I'm trying to serialize this Configuration object, but for the life of me I can't get it. I've checked everywhere including StackOverflow. Any help would be greatly appreciated.
Serialization Code:
public void serialize(String outFile)
throws IOException {
Configuration config = new Configuration().getConfiguration();
System.out.println(config.email);
try
{
FileOutputStream outputFile =
new FileOutputStream("/home/jason/Desktop/config.ser");
ObjectOutputStream objectOutput = new ObjectOutputStream(outputFile);
objectOutput.writeObject(config);
objectOutput.close();
outputFile.close();
}catch(IOException i)
{
i.printStackTrace();
}
System.out.println(config);
}
public void deSerialize()
throws FileNotFoundException, IOException, ClassNotFoundException {
Configuration config = new Configuration().getConfiguration();
try
{
FileInputStream inputFile = new FileInputStream("/home/jason/Desktop/config.ser");
ObjectInputStream objectInput = new ObjectInputStream(inputFile);
config = (Configuration) objectInput.readObject();
config.setConfiguration(config);
objectInput.close();
inputFile.close();
}catch(Exception e)
{
e.printStackTrace();
}
System.out.println(config);
}
And then I call it with the following code:
DataStore data = new DataStore().getInstance();
try {
data.deSerialize();
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
DataStore is a simple singleton, and takes no input parameters. It doesn't have any real variables, but simply employs the serialization functions.
Finally, here is my Configuration code:
public class Configuration implements Serializable{
private static final long serialVersionUID = 1388190376766023647L;
public static String email = "";
private static String ip = "";
private static String password = "";
private static String importNumber;
private static Configuration configuration;
private static int singleton = 0;
public String value_of_da_message;
public Configuration()
{}
public Configuration getConfiguration()
{
if(singleton == 0){
configuration = new Configuration();
singleton++;
return configuration;
}
else
return configuration;
}
public void setConfiguration(Configuration config)
{
configuration = config;
}
Any clue on where I'm going wrong? Thanks for the help.
Have a look here: Java static serialization rules?
Change your fields to be instance fields, which would better fit the singleton approach anyways.
The fields might be serialized but deserialization normally ignores static fields.
Additionally, it looks like you're reading to the temporary object:
config.setConfiguration(config);
This uses the read object twice and doesn't set the data of the singleton unless you keep that a static field (i.e. configuration in the Configuration class is the reference to the singleton and needs to be static)
Update:
Another hint: the static variable singleton might cause problems and is unneeded anyway. Just check configuration == null instead of singleton == 0.
Hint:
I try to help you with serialization in general, but in your special case you might want to use Properties instead which have built-in serialization features (.properties- and xml-files supported) and which are meant for configuration.
Related
My university professor shared this class with us (it's essentially a generic parser using Gson):
public abstract class GenericDAO<T> {
final Class<T> clase;
protected File archivo;
public GenericDAO(Class<T> clase, String file) throws Exception {
this.clase = clase;
this.archivo = new File(file);
this.archivo.createNewFile();
}
public List<T> getAll(Class<T> clase) throws Exception {
List<T> list = new ArrayList<T>();
FileReader f = new FileReader(archivo);
BufferedReader b = new BufferedReader(f);
Gson g = new Gson();
String line = "";
try {
while ((line = b.readLine()) != null && !line.equals("")) {
JsonParser parser = new JsonParser();
JsonObject jsonObject = parser.parse(line).getAsJsonObject();
list.add(g.fromJson(jsonObject, clase));
}
b.close();
} catch (Exception e) {
e.printStackTrace();
return list;
}
return list;
}
// a lot of other methods to read/write to json files
}
I created a class that inherits from it so I can read a Business from a file:
public class Business extends GenericDAO<Business> {
private String name;
// a lot of other members
// this was automatically generated by Intellij:
public Business(Class<Business> clase, String file) throws Exception {
super(clase, file);
}
}
Intellij automatically generated a constructor for it, but I don't understand it. Why does the constructor has a class as a parameter, do I have to pass an instance of itself to it? That doesn't make sense.
I would be grateful if you can point me to either some documentation to read through, or explain the pattern my professor is using.
Edit: to sum up, how do I instantiate my business class then? This is throwing an error:
Business client = new Business(Business, "path_to_json_file.json");
This wouldn't fit well in a comment: you could use a different style of constructor if you want. Replace this:
// this was automatically generated by Intellij:
public Business(Class<Business> clase, String file) throws Exception {
super(clase, file);
}
With this:
public Business(String file) throws Exception {
super( Business.class, file);
}
Which I think is more like your instructor may have intended.
I am starting to program a Code Generator for NetBeans 8, and I am having trouble figuring out the best way to test its invoke() method.
The code generator I want to test is basically like this:
(imports here)
public class MyCodeGenerator implements CodeGenerator {
private final JTextComponent textComponent;
private final CompilationController controller;
MyCodeGenerator(final Lookup context) {
textComponent = context.lookup(JTextComponent.class);
controller = context.lookup(CompilationController.class);
}
#Override
public String getDisplayName() {
return "Generate Some Code...";
}
/**
* This will be invoked when user chooses this Generator from Insert Code
* dialog
*/
#Override
public void invoke() {
if (textComponent != null && controller != null) {
controller.toPhase(Phase.RESOLVED);
//do more things with the source code;
}
}
}
I want to use a mocked (Mockito) object for Lookup, to pass to the MyCodeGenerator's constructor. The mock should return the JTextComponent and the CompilationController.
I know I can provide a JTextComponent with the test code, but I hit the wall when I need to provide a CompilationController.
I can create a temporary java source file with the same content as the JTextComponent, but I could not find a way to create a CompilationController (or WorkingCopy) from it.
This is what I tried so far (my test method):
#Test
public void testInvoke() throws ParseException, IOException {
System.out.println("invoke");
final ExtractControllerTask extractTask = new ExtractControllerTask(
Phase.RESOLVED);
final StringBuilder builder = new StringBuilder(100);
final JTextComponent textComponent;
final Document document;
final FileObject javaTestFile;
final OutputStream outputStream;
final JavaSource source;
builder.append("public class Clazz {");
builder.append("private int a = 2;");
builder.append("}");
textComponent = new JTextArea(builder.toString());
document = textComponent.getDocument();
document.putProperty(BaseDocument.MIME_TYPE_PROP, "text/x-java");
javaTestFile = FileUtil.createData(new File(
"/tmp/javaTestSourceFile.java"));
outputStream = javaTestFile.getOutputStream();
outputStream.write(builder.toString().getBytes());
outputStream.flush();
source = JavaSource.forFileObject(javaTestFile);
assertNotNull(source);
source.runUserActionTask(extractTask, true);
assertNotNull(extractTask.controller); //FAILS HERE
}
This is the code for ExtractControllerTask:
private static class ExtractControllerTask implements
Task<CompilationController> {
private final Phase targetPhase;
private CompilationController controller;
private ExtractControllerTask(final Phase phase) {
this.targetPhase = phase;
}
public void run(final CompilationController compControler) {
try {
compControler.toPhase(this.targetPhase);
this.controller = compControler;
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
}
What surprises me is that the run method in ExtractControllerTask is never called.
I really need to test my code but I can't find the proper way. Maybe the approach is completely wrong.
Can anyone suggest how to achieve this?
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
}
}
I am trying to write a custom converter for a byte[] in Simple XML. It is working half way meaning invoking the write method but not the read. Can someone point out why??
Here is my simple xml annotated object
#Root
public class Device implements Serializable
{
private final static long serialVersionUID = 1L;
#Element
#Convert(ByteArrayConverter.class)
protected byte[] imageRef;
public byte[] getImageRef() {
return imageRef;
}
public void setImageRef(byte[] imageRef) {
this.imageRef = imageRef;
}
Here is my custom converter
public class ByteArrayConverter implements Converter<byte[]>
{
#Override
public byte[] read(InputNode node) throws Exception
{
//put a break point here BUT Code not getting here
("I am here in read")
String s = node.getValue();
return Base64.decode(s);
}
#Override
public void write(OutputNode node, byte[] byteArray) throws Exception
{
("I am here in write")
node.setValue(Base64.encode(byteArray))
}
Here is my serialization/deserialization code
Registry registry = new Registry();
Strategy strategy = new RegistryStrategy(registry);
Serializer serializer = new Persister(strategy);
try
{
registry.bind(byte[].class, ByteArrayConverter.class);
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Device device = new Device();
device.setImageRef(new byte[]{1,2,3});
File file = new File("myDevice.xml");
serializer.write(device, file);
Device readDevice = serializer.read(Device.class, file);
When I execute this in debugger I do see the debugger stopping in write method however it doesn't stop in read() method and hence I am not getting expected result. Any reason why this code do not stop in reading when we are constructing the object back??? Thanks
When i run this demo it's call TestBean's writeObject method which is private
How is it possible ?
Here is the Code:
import java.io.FileOutputStream;
public class Test {
public static void main(String[] args) {
try {
TestBean testBean = test.new TestBean();
testBean.setSize(23);
testBean.setWidth(167);
FileOutputStream fos =
new FileOutputStream(new File("d:\\serial.txt"));
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(testBean);
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
class TestBean implements Serializable {
private static final long serialVersionUID = 1L;
private int size;
private int width;
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
private void writeObject(ObjectOutputStream out) throws IOException {
System.out.println("TestBean writeObject");
out.defaultWriteObject();
}
private void readObject(ObjectInputStream input) throws IOException,
ClassNotFoundException {
System.out.println("TestBean readObject ===================> ");
input.defaultReadObject();
}
}
}
If your serializable object has any writeObject method, it will be called otherwise the defaultWriteObject method will be called.
The private method calling is possible using the reflection. If you see the source code of ObjectOutputStream Class in that method writeSerialData, the code below answers your question.
if (slotDesc.hasWriteObjectMethod()) {
// through reflection it will call the Serializable objects writeObject method
} else {
// the below is the same method called by defaultWriteObject method also.
writeSerialData(obj, desc);
}
The virtual machine will automatically check to see if either method
is declared during the corresponding method call. The virtual machine
can call private methods of your class whenever it wants but no other
objects can. Thus, the integrity of the class is maintained and the
serialization protocol can continue to work as normal. The
serialization protocol is always used the same way, by calling either
ObjectOutputStream.writeObject() or ObjectInputStream.readObject().
So, even though those specialized private methods are provided, the
object serialization works the same way as far as any calling object
is concerned.
You will get more about from this article:
Discover the secrets of the Java Serialization API
It uses reflection. private and public are not security measures. That is only a contract for class users.