Serialize classes

Post Reply
flucatcher
Posts: 74
Joined: Mon Jan 28, 2019 5:51 am

Serialize classes

Post by flucatcher »

Hi, trying to save some presets but get problems when trying to serialize a class. Class code looks like this:
class Effect implements java.io.Serializable {
private static final long serialVersionUID = 1;

private int algorithmIndex = 0;
private double amount = 0;

public Effect() {
}

public Effect(int algorithmIndex, double amount) {
this.algorithmIndex = algorithmIndex;
this.amount = amount;
}

public void setAlgorithmIndex (int algorithmIndex) {
this.algorithmIndex = algorithmIndex;
}

public int getAlgorithmIndex () {
return this.algorithmIndex;
}

public void setAmount (double amount) {
this.amount = amount;
}

public double getAmount () {
return this.amount;
}
}

Serialization code (added to the init function for a simple example):
Effect serializeObject = new Effect(1, 0.5);

byte[] stream = null;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);) {
oos.writeObject(serializeObject);
stream = baos.toByteArray();
Log("Serialization ok");
} catch (IOException e) {
// Error in serialization
e.printStackTrace();
Log("IOException is caught: " + e);
}

The only other added code is:
import java.io.*;

Code works well when running it with java in a separate file but fails in the designer.

Running jdk1.8.0_202 on windows 10.

Would be really happy for some help on this or sample code on how to serialize an array of objects that works in module designer (not a great java developer, module designer is the only reason I use java :)).
User avatar
nekomatic
Posts: 64
Joined: Mon Jul 08, 2019 8:52 pm

Re: Serialize classes

Post by nekomatic »

I had the same problem but ended up creating all the serialization logic by hand... I've actually sent a feature request to CA this weekend to add serialization features to the VM API... Lets see what they come back with...

In the meantime if this module is for private use and you dont like to fiddle with bitshifting etc. you may simply convert all values to a comma separated string and save it as bytes, for deserialization you will only need to parse the comma separated chuncks of text. Not the prittiest way but unfortunately Java doesnt seem to provide out of the box getBytes() / fromBytes() functionality for primitive types... I'm also new to Java so may be I've meesed somathig... :)
flucatcher
Posts: 74
Joined: Mon Jan 28, 2019 5:51 am

Re: Serialize classes

Post by flucatcher »

Hey, thanks for the quick reply! Glad im not the only one with the same problem.

I tried a bit more and got it working by making the class I wanted to serialize external. Here is the code.

Added SerializeTestClass.java and added it as addidional java file.

Code: Select all

package com.flucatcher;

import java.io.*;

public class SerializeTestClass implements java.io.Serializable 
{ 
	private static final long serialVersionUID = 1;
	
	public int a; 
	public String b; 
	public double c; 
  
    // Default constructor 
    public SerializeTestClass(int a, String b, double c) 
    { 
        this.a = a; 
        this.b = b; 
        this.c = c; 
    } 
  
}
Added serialization and deserialization code in the init function (just as a test):

Code: Select all

      SerializeTestClass serializeObject = new SerializeTestClass(1, "2", 3.4);
      
		byte[] stream = null;
		try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
		     ObjectOutputStream oos = new ObjectOutputStream(baos);) {
			oos.writeObject(serializeObject);
			stream = baos.toByteArray();
			Log("Serialization ok, length is: " + stream.length); 
		} catch (IOException e) {
			// Error in serialization
			e.printStackTrace();
			Log("IOException is caught: " + e); 
		}
		
		ObjectInput in = null;
		try {
			ByteArrayInputStream bis = new ByteArrayInputStream(stream);
			in = new ObjectInputStream(bis);
			SerializeTestClass o = (SerializeTestClass)in.readObject();
			Log("Deserialize ok: " + o.a); 
		} 
		catch (Exception e) {
			Log("Deserialize exception: " + e); 
		}
		finally {
		  try {
		    if (in != null) {
		    	in.close();
		    }
		  } catch (IOException ex) {
		  }
		}
Not sure why its not working with SerializeTestClass defined in the main file.
User avatar
nekomatic
Posts: 64
Joined: Mon Jul 08, 2019 8:52 pm

Re: Serialize classes

Post by nekomatic »

I would normally approach this problem like you did when working on some enterptise system (but not in Java obviously) but in case of a DSP module I think you are overcomplicating your code.
What you need is just to preserve some values, it's OK to make a bespoke one-off routine in core Java which takes the exact values and puts them onto an array directly and the other way around. You dont want your code to be heavy, and most of all you do not want your code to throw exceptions - serialization is a pure function, set A is mapped to set B, there are no side-effects. If you believe your code has a chance to throw an exception then you should try to prove your code rather than let it fail during runtime.
flucatcher
Posts: 74
Joined: Mon Jan 28, 2019 5:51 am

Re: Serialize classes

Post by flucatcher »

I agree that the approach was a bit messy. I ended up using a JSON serializer instead (google Gson), seems to work fine and should not break if I add additional properties.
Cherry Dan
Site Admin
Posts: 257
Joined: Fri Jul 27, 2018 5:36 pm

Re: Serialize classes

Post by Cherry Dan »

What error message is the Module Designer giving you when you try to compile that code?

We use Serializable classes in Cherry Audio modules and they work fine.

Thanks,
Dan
flucatcher
Posts: 74
Joined: Mon Jan 28, 2019 5:51 am

Re: Serialize classes

Post by flucatcher »

20:20:49.399 IOException is caught: java.io.NotSerializableException: com.mycompany.newmodule.MyModule
20:20:49.400 CInterAppCommChannel::SendMessage: wrote 138 bytes
20:20:49.400 Deserialize exception: java.lang.NullPointerException
20:20:49.400 CInterAppCommChannel::SendMessage: wrote 102 bytes

When I move the class definition out to a separate file it works fine.
Cherry Dan
Site Admin
Posts: 257
Joined: Fri Jul 27, 2018 5:36 pm

Re: Serialize classes

Post by Cherry Dan »

This is a little complex, but it's failing because the inner class has access to members of the outer class, and the outer class is not Serializable.

There are two ways to fix this.

1. Make your inner class static. All you need to do is change it from

public class Effect implements java.io.Serializable

to

public static class Effect implements java.io.Serializable

..and your code will work.

2. Make your module class implement Serializable. You can do that at the top of the code:

public class MyModule extends VoltageModule
implements java.io.Serializable

However, making the inner class static is really the correct approach. Here's a short article on the subject: https://rules.sonarsource.com/java/tag/ ... RSPEC-2059

Here's another one: https://help.semmle.com/wiki/display/JA ... able+class

I hope that helps! This is a Java coding issue, and is in no way unique to Voltage Modular.

Dan
flucatcher
Posts: 74
Joined: Mon Jan 28, 2019 5:51 am

Re: Serialize classes

Post by flucatcher »

Thanks! Updated my test code and it works.
Post Reply

Return to “Module Designer”