Trying to serialize and send Lot object to socket. Getting error:
java.io.NotSerializableException: com.server.ClientServiceThread
Why?
public class ClientServiceThread extends Thread {... // form here called sendObj ...}
public class FlattenLot {
public void sendObj(){
try {
out = new ObjectOutputStream(oStream);
out.writeObject(lot); // error
out.flush();
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
Lot class:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.util.Calendar;
public class Lot implements Serializable{
private static final long serialVersionUID = 1L;
public ArrayList<ClientServiceThread> clientBidsLog = new ArrayList<ClientServiceThread>();
public ArrayList<Integer> bidLog = new ArrayList<Integer>();
private List<Integer> bids = new ArrayList<Integer>();
private List<ClientServiceThread> clients = new ArrayList<ClientServiceThread>();
private String NAME;
private int INITIAL_PRICE;
private int MAX_BID = 0;
public volatile boolean notAvailable = false;
Lot(String name, int initPrice){
NAME = name;
INITIAL_PRICE = initPrice;
}
public synchronized String getName(){return NAME;}
public synchronized int getInitPrice(){return INITIAL_PRICE;}
public synchronized void subscribe(ClientServiceThread t){
clients.add(t);
}
public synchronized void unsubscribe(ClientServiceThread t){
clients.remove(t);
}
public synchronized boolean makeBid(ClientServiceThread t,int i){
if(i > INITIAL_PRICE && i > MAX_BID){
clientBidsLog.add(t);
bidLog.add(i);
bids.add(i);
MAX_BID = i;
t.LAST_BID = i;
notifyAllSubscribers("New bid: "+this.getMaxBid()+" made by "+this.clientBidsLog.get(this.clientBidsLog.size()-1).CLIENT_NAME);
return true;
}else{
return false;
}
}
public synchronized void notifyAllSubscribers(String msg){
for (ClientServiceThread client : clients){
client.lotUpdated(this, msg);
}
}
public synchronized int getMaxBid(){return MAX_BID;}
private Date time;
public Lot() {
time = Calendar.getInstance().getTime();
}
public Date getTime() {
return time;
}
}
The error is caused by trying to serialize a ClientServiceThread, which is not serializable. Somehow one of those is part of a Lot. If Lot is not declared with a ClientServiceThread field (or with a field that contains a ClientServiceThread), then another possibility is that Lot is a non-static inner class of a class that does have such a field. The outer class instance would then be a (hidden) member of Lot.
The solution is to either make ClientServiceThread serializable (not likely, from its name) or else eliminate it from the serialization by marking the relevant field(s) transient (or removing them from the Lot class).
Lot contains
public ArrayList<ClientServiceThread> clientBidsLog
private List<ClientServiceThread> clients
If you wish this field to be serialized mark the ClientServiceThread serializable too
if you don't want it to be serialized just mark it transient like
public transient ArrayList<ClientServiceThread> clientBidsLog
private transient List<ClientServiceThread> clients
A couple of answers have suggested that you could declare ClientServiceThread serializable as a possible solution.
WARNING - that probably won't work!
Yes, you can declare a Thread subclass that implements Serializable, but the Java serialization mechanism can't serialize the stack of a live thread. In fact, I don't even think it will succeed in serializing an inactive thread's state (e.g. the thread's ThreadGroup reference), so you'll probably end up the more exceptions.
I think your only option is to exclude the threads from serialization by declaring those collections to be transient.
Related
I was writing this piece of code to understand reflection and encountered one scenario where I couldn't really figure out the reason for the codes' behavior. Hopefully I receive some guidance from the community.
Following is my test model class & here, for every instantiation, I want to know the exact number of instances created during runtime (using reflection)
public final class Model {
private static final Model instance = new Model("Testing");
private static int count = 0;
private String name;
private Model(String name) {
this.name = name;
++count;
}
public static Model getInstance() {
return instance;
}
public static int getInstanceCount() {
return count;
}
public String getName() {
return name;
}
public void doSomething() {
try {
System.out.println("Shh.... I am trying to do something");
Thread.sleep(1000);
System.out.println("Ok! Done.");
return;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Oops! I failed in doing your job...");
}
}
The driver code for this scenario is as follows,
public class ReflectionTest {
public static void main(String[] args) throws Exception {
Model.getInstance().doSomething();
System.out.println(Model.getInstanceCount());
Constructor<?>[] constructor = Model.class.getDeclaredConstructors();
for (Constructor<?> aConstructor : constructor) {
aConstructor.setAccessible(true);
Model m = (Model) aConstructor.newInstance("Testing through Reflection");
System.out.println(m.getName());
m.doSomething();
System.out.println(m.getInstanceCount());
//System.out.println(Model.getInstanceCount());
}
}
}
The output for this above piece of code came out to be as follows,
Shh.... I am trying to do something
Ok! Done.
0
Testing through Reflection
Shh.... I am trying to do something
Ok! Done.
1
As you can see, the instance count came out to be 1. I expected it to be as 2.
However, I changed the test model class's constructor as shown below. The datatype of count is now changed to Integer, instead of previously set 'int'.
private Model(String name) {
this.name = name;
if (count == null)
count = 0;
++count;
}
Surprisingly, I get the correct value for the instance count.
Shh.... I am trying to do something
Ok! Done.
1
Testing through Reflection
Shh.... I am trying to do something
Ok! Done.
2
This might be a silly question, but I am not able to ponder on what really happened behind the scenes. I need some guidance from the community on this.
Thanks in advance.
This has nothing to do with reflection.
private static final Model instance = new Model("Testing");
private static int count = 0;
The initializers are executed in order. So:
private static final Model instance = new Model("Testing");
Executing the constructor causes count to be incremented from 0 to 1, but then:
private static int count = 0;
Sets count back to zero.
Reverse the order of the declarations.
private static int count = 0;
private static final Model instance = new Model("Testing");
Or omit the initializer on count (its default value is zero anyway).
private static final Model instance = new Model("Testing");
private static int count;
I'm new to Java programming, sorry if this is a dumb question.
I find it hard to word this question properly, but I have an assignment to create a aircraft class that can make aircraft land, takeoff etc. And need to test it using Testclass. When the new object are entered it automatically assigns a unique ID to the aircraft in the constructor.
I can do this using a instance method fine as it has a return value which is returned to to Testclass. The question wants me to do this in the constructor itself, however, the constructor never returns anything. So the variable never gets sent to the Testclass. I clearly am not understanding OOP properly. Even when I try to just use a getter method to get the ID created in the constructor it gives me the initialized variable before the the constructor has worked on this. This is the code I have so far and its completely wrong I know but if someone could point me in the right direction or tell me how to word this question better it would be a massive help.
// I need to enter 3 aircraft into the system in the testclass
public class Aircraft {
private int aircraftID;
private static int lastID;
private String airportcode;
private int ID = 100;
private int count;
public Aircraft(int a, int b, int c){
// Constructor
// Assign ID
this.ID = a;
lastID = ID;
ID++;
this.ID =b;
lastID = ID;
ID++;
}
}
OK, you want to create an Aircraft that has an automatically-assigned unique identifier, and can take off and land. That implies you need a field for tracking the identifier, a field for tracking whether it's in the air (or not), and methods for the take off and land operations. You also need a static field for generating the unique identifiers. (Note that this implementation isn't thread safe.)
private class Aircraft {
private static int staticId = 0;
private int uniqueId = 0;
private boolean onGround = true; // Aircraft start on the ground in this implementation
public Aircraft(){
this.uniqueId = staticId; // putting this line first makes uniqueId zero-indexed in effect
staticId++;
}
public void land(){
onGround = true;
}
public void takeoff(){
onGround = false;
}
public boolean isFlying(){
return !onGround; // If it's not on the ground, it's flying
}
public int getUniqueId(){
return uniqueId;
}
}
Unit tests checks all of the methods and expected functionality of the class in question:
import org.junit.Test;
import static org.junit.Assert.*;
import Aircraft;
class Testclass {
private final Aircraft aircraft = new Aircraft();
#Test
public void hasId(){
aircraft.getUniqueId() >= 0;
}
#Test
public void canLand(){
assertTrue(aircraft.land());
}
#Test
public void canTakeOff(){
assertTrue(aircraft.takeOff());
}
#Test
public void checkFlightOperationsAreTrackedCorrectly(){
aircraft.land();
assertFalse(aircraft.isFlying());
aircraft.takeOff();
assertTrue(aircraft.isFlying());
}
}
As pointed out a constructor does not return anything (the simplified version is that with new it returns an object instance). I am kinda guessing at what you are trying to acomplish, but I'll have a go anyways. It seems to me that you are trying to cram the construction of 3 objects into one constructor - which is why your constructor has 3 parameters. Also you are playing havoc with the IDs.
I have removed all the variables that I didnt quite understand, leaving only ID that increments with each instantiated Aircraft. The #Override is mainly just for show.
public class Aircraft {
private int aircraftID;
private static int lastID = 0;
#Override
public String toString(){
return "Aircraft_" + this.aircraftID;
}
public Aircraft() {
lastID++;
this.aircraftID = lastID;
}
}
I took the liberty and wrote the TestClass just to see if we have the same thing in mind. Again the printAircraft() method is for show.
public class TestClass {
private List<Aircraft> aircrafts;
public TestClass(){
aircrafts = new ArrayList<>();
}
public void addAircraft(Aircraft a){
aircrafts.add(a);
}
public void printAircraft(){
Iterator<Aircraft> it = aircrafts.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
}
and to test it, we create and instance of TestClass add 3 Aircraft instances and print out the contents
public static void main(String[] args) {
TestClass tc = new TestClass();
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.printAircraft();
}
This would be the case if you are to write the TestClass. If that is given, it would help to know what it looks like - maybe that would help us understand better.
When reading Effective Java I found that the most useful approach to implement singletons is just using enums with single INSTANCE. But in case we need to make it a class, according to some of his susggestions the perfect serializable thread-safe singleton class would look like this:
public class SerializableSingletonClass implements Serializable{
private static final long serialVersionUID = 1L;
private int value;
private String name;
private SerializableSingletonClass(int value, String name) {
if( value < 0 ) throw new IllegalArgumentException("Value may not be less than 0");
this.value = value;
this.name = Validate.notNull(name, "Name may not be null");
}
private static class SerializableSingletonHolder{
public static final SerializableSingletonClass INSTANCE;
static {
INSTANCE = new SerializableSingletonClass(0, "default");
}
}
private void readObject(ObjectInputStream stream) throws InvalidObjectException{
throw new InvalidObjectException("proxy required");
}
private Object writeReplace(){
return new SerializationProxy(this);
}
private static class SerializationProxy implements Serializable{
private static final long serialVersionUID = 1L;
public SerializationProxy(SerializableSingletonClass ignored) { } //Here is the question
private Object readResolve(){
return SerializableSingletonHolder.INSTANCE;
}
}
}
As far as I got he proposed to just replace serialized instances with one that's used currently.
So, why do we ever need to make singletons serializable in the owing that their serial form would not be ever used. We just throw it out and replace deserialized instance with the current one.
To me the problem of implementing serializable singletons looks like only a theoretical one. Accoring to what I said, deserializing singleton doesn't make much sense (in the case of enums either).
So what did I miss? Couldn't you explain it in a bit more detail?
enums are also serializable, just not their fields.
I think it's important to keep it simple and easy to maintain e.g. use a text file if you are going to save it.
I would add a method like save and load to it (possibly with a filename)
enum SaveableSingleton {
INSTANCE;
String name;
int value;
public void load(String filename) throws IOException {
try (Scanner scanner = new Scanner(new File(filename))) {
name = scanner.nexLine();
value = scanner.nextInt();
}
}
public void save(String filename) throws IOException {
try (PrintWriter pw = new PrintWriter(new File(filename))) {
pw.println(name);
pw.println(value);
}
}
}
creates a file like
my-name-is
12345
If you have some field in some other serializable class where you store this singleton instance and want to serialize / deserialize that class, you would always have to mark that field transient and make sure to fill it manually on deserialization. If you handle it in the Singleton, you don't have to do this. I guess that is the reason for a serializable singleton.
I have some class storing keys with important information. No one else is allowed to create a key, since a key relys on static information (like certain directory structures etc.).
public final class KeyConstants
{
private KeyConstants()
{
// could throw an exception to prevent instantiation
}
public static final Key<MyClass> MY_CLASS_DATA = new Key<MyClass>("someId", MyClass.class);
public static class Key<T>
{
public final String ID;
public final Class<T> CLAZZ;
private Key(String id, Class<T> clazz)
{
this.ID = id;
this.CLAZZ = clazz;
}
}
}
This example is simplyfied.
I wanted to test the consequences of a wrong key (exception handling, etc.) and instantiated the class via reflection in a JUnit test case.
Constructor<?> c = KeyConstants.Key.class.getDeclaredConstructor(String.class, Class.class);
c.setAccessible(true);
#SuppressWarnings ("unchecked")
KeyConstants.Key<MyClass> r = (KeyConstants.Key<MyClass>) c.newInstance("wrongId", MyClass.class);
Then I asked myself how could I prevent further instantiation of the key class (i. e. preventing further object creating via reflection)?
enums came to my mind, but they don't work with generics.
public enum Key<T>
{
//... Syntax error, enum declaration cannot have type parameters
}
So how can I keep a set of n instances of a generic class and prevent further instantiation?
So how can I keep a set of n instances of a generic class and prevent
further instantiation?
If you truly want to use this pattern, then no one (including you) should be able to instantiate a Key object. In order to keep a set of n instances in a class with this pattern, you could have a private constructor, a static method for access and a SecurityManager to prevent reflection. And since you want to be able to access the keys as pubic constants, I would try something like this..
public class KeyConstants{
// Here are your n instances for public access
public static final int KEY_1 = 1;
public static final int KEY_2 = 2;
.
.
.
public static final int KEY_N = 'n';
// now you can call this method like this..
// Key mKey = KeyConstants.getKey(KeyConstants.KEY_1);
public static Key getKey(int key){
List keys = Key.getInstances();
switch(key){
case KEY_1:
return keys.get(0);
case KEY_2:
return keys.get(1);
.
.
.
case KEY_N:
return keys.get(n);
default:
// not index out of bounds.. this means
// they didn't use a constant
throw new IllegalArgumentException();
}
}
static class Key<T>{
private static List<Key> instances;
private String ID;
private Class<T> CLAZZ;
private Key(String id, Class<T> clazz){
this.ID = id;
this.CLAZZ = clazz;
}
public static List<Key> getInstances(){
if(instances == null){
instances = new ArrayList<Key>();
//populate instances list
}
return instances;
}
}
}
Use SecurityManager to prevent reflection access.
//attempt to set your own security manager to prevent reflection
try {
System.setSecurityManager(new MySecurityManager());
} catch (SecurityException se) {
}
class MySecurityManager extends SecurityManager {
public void checkPermission(Permission perm) {
if (perm.getName().equals("suppressAccessChecks"))
throw new SecurityException("Invalid Access");
}
}
This will throw a SecurityException anytime someone attempts to access a private variable or field in your class (including access attempts via reflection).
I'm not sure I fully understand your question, but if a private constructor is not sufficient, can you use a more dynamic approach and throw an exception in the constructor after a signal is given? For example:
public static class Key<T>
{
private static boolean isLocked = false;
// Call this method when you want no more keys to be created
public static void lock() { isLocked = true; }
...
private Key(String id, Class<T> clazz)
{
if (isLocked) throw new IllegalStateException("Cannot create instances of Key");
this.ID = id;
this.CLAZZ = clazz;
}
}
Then - and this is the disadvantage - you will have to call Key.lock() once you want to prevent more instances being created.
As you showed in your code to prevent instantiating KeyConstants you can throw some Exception inside private-non-argument constructor.
Harder part is way to block creating KeyConstants.Key constructor from outside of KeyConstants class.
Some wild idea
Maybe create Exception in your constructor and check how its stack trace looks like. When I add this code to constructor
private Key(String id, Class<T> clazz) {
StackTraceElement[] stack = new Exception().getStackTrace();
for (int i=0; i<stack.length; i++){
System.out.println(i+") "+stack[i]);
}
this.ID = id;
this.CLAZZ = clazz;
}
and create instance of Key with reflection like
Constructor<?> c = KeyConstants.Key.class.getDeclaredConstructor(
String.class, Class.class);
c.setAccessible(true);
KeyConstants.Key<MyClass> r = (KeyConstants.Key<MyClass>) c
.newInstance("wrongId", MyClass.class);
I get
0) KeyConstants$Key.<init>(Test.java:38)
1) sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
2) sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
3) sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
4) java.lang.reflect.Constructor.newInstance(Constructor.java:525)
so maybe just if 4th element of stack is java.lang.reflect.Constructor.newInstance throw Exception to prevent executing rest of constructors code like:
if (stack.length>=4 && stack[4].toString().startsWith("java.lang.reflect.Constructor.newInstance")){
throw new RuntimeException("cant create object with reflection");
}
I came across some Multiton patterns recently, where I tried to handle problems with unique enum keys, that gave me the idea of another approach.
The keys can be used for information flow as I intended, or even as keys for typesafe heterogeneous container, where they can perform compile-time casting.
Key-defining class
public class KeyConstants
{
public static final KeysForIntegers SOME_INT_KEY = KeysForIntegers.KEY_2;
public static final KeysForStrings SOME_STRING_KEY = KeysForStrings.KEY_1;
public interface Key<Type>
{
public Class<Type> getType();
}
/* Define methods that classes working with the keys expect from them */
public interface KeyInformation
{
public String getInfo1();
// and so on...
}
public enum KeysForStrings implements Key<String>, KeyInformation
{
KEY_1("someId");
public final String ID;
private KeysForStrings(String id)
{
ID = id;
}
#Override
public String getInfo1()
{
return "Good piece of information on " + ID + ".";
}
#Override
public Class<String> getType()
{
return String.class;
}
}
public enum KeysForIntegers implements Key<Integer>, KeyInformation
{
KEY_2("bla");
public final String ID;
private KeysForIntegers(String id)
{
this.ID = id;
}
#Override
public String getInfo1()
{
return "Some info on " + ID + ".";
}
#Override
public Class<Integer> getType()
{
return Integer.class;
}
}
}
Example key-using class
public class KeyUser
{
public static void main(String[] args)
{
KeysForIntegers k1 = KeyConstants.SOME_INT_KEY;
KeysForStrings k2 = KeyConstants.SOME_STRING_KEY;
processStringKey(k2);
useIntKey(k1);
Integer i = useIntKey(KeyConstants.SOME_INT_KEY);
processStringKey(KeyConstants.SOME_STRING_KEY);
}
/* My methods should just work with my keys */
#SuppressWarnings ("unchecked")
public static <TYPE, KEY extends Enum<KeysForIntegers> & Key<TYPE> & KeyInformation> TYPE useIntKey(KEY k)
{
System.out.println(k.getInfo1());
return (TYPE) new Object();
}
public static <KEY extends Enum<KeysForStrings> & KeyInformation> void processStringKey(KEY k)
{
System.out.println(k.getInfo1());
// process stuff
}
}
I have another approach, you can bound an interface in a way to only be implemented by enum.
With that approach you have a fixed set of instances at compile time.
If you want to add lazy loading, the enums implementing it should be proxies that load the desired object if it is requested. The class or classes that are hidden behind the proxies should only be visible to them, so that they have exclusive access to the constructor.
public class User {
public static <S> S handleKey(FixedInstanceSet<S,?> key) {
return key.getKey();
}
}
interface FixedInstanceSet<S, T extends Enum<T> & FixedInstanceSet<S,T>>
{
public S getKey();
}
enum StringKeys implements FixedInstanceSet<String, StringKeys> {
TOP, DOWN, LEFT, RIGHT;
#Override
public String getKey() { return null; }
}
enum IntKeys implements FixedInstanceSet<Integer, IntKeys > {
TOP, DOWN, LEFT, RIGHT;
#Override
public Integer getKey() { return null; }
}
/*
* Bound mismatch: The type NotWorking is not a valid substitute for the bounded
* parameter <T extends Enum<T> & FixedInstanceSet<S,T>> of the type
* FixedInstanceSet<S,T>
*/
//class NotCompiling implements FixedInstanceSet<String, NotCompiling> {
//
// #Override
// public String getKey() { return null; }
//}
If I understand you correctly, you don't want your class to be instantiated.
You can set the default constructor to private
private Key() throws IllegalStateException //handle default constructor
{
throw new IllegalStateException();
}
This will prevent its improper instantiation.
Update:
added throw IllegalStateException
I have encountered a weird problem in my app (java).
I have an enum. Something like that
public enum myEnum implement myIntrface{
valueA(1),valueb(2),valuec(3),valued(4)
private int i;
// and then - a constructor
public MyEnum(int number){
i = number;
}
private MyObj obj = new MyObj;
// getter and setter for obj
}
and in another class I have this
MyEnum.valueA.setObj(new Obj(...))
in briefe - I have an enum with a private instance member that has a set and a get.
So far so good -
The only thing that amazes me is that later on I look at the value of the MyEnum.valueA().obj is null.
there is nothing that updates the value to null, I have even gave it a default value in the constructor and I still see it null later.
any suggestions?
Enums should be un-modifiable classes so you shouldn't really be doing this. If your looking to modify the state of a type based object like an enum you should use an final class approach with embedded constants. Below is an example of a class based approach with a modifiable name an a un-modifiable name...
public final class Connection {
public static final Connection EMAIL = new Connection("email");
public static final Connection PHONE = new Connection("phone");
public static final Connection FAX = new Connection("fax");
/**/
private final String unmodifiableName; //<-- it's final
private String modifiableName;
/*
* The constructor is private so no new connections can be created outside.
*/
private Connection(String name) {
this.unmodifiableName = name;
}
public String getUnmodifiableName() {
return unmodifiableName;
}
public String getModifiableName() {
return modifiableName;
}
public void setModifiableName(String modifiableName) {
this.modifiableName = modifiableName;
}
}
The purpose of enums is to represent constant values. It does not make any sense to set the fields of a constant value.
You should declare your fields as final, and use the constructor to initialize all of them.
For reference, the following code works as expected:
public class Test {
public static enum MyEnum {
valueA(1),valueb(2),valuec(3),valued(4);
private int i;
private Object o;
private MyEnum(int number) {
i = number;
}
public void set(Object o) {
this.o = o;
}
public Object get() {
return o;
}
}
public static void main(String[] args) {
System.out.println(MyEnum.valueA.get()); // prints "null"
MyEnum.valueA.set(new Integer(42));
System.out.println(MyEnum.valueA.get()); // prints "42"
}
}
the cause of this problem is the db40 framework . It loads an enum from the db using reflection. This is well documented .
http://developer.db4o.com/Forums/tabid/98/aft/5439/Default.aspx