Skip to main content

Recent changes

  9 posts   Feedicon  
Replies: 8 - Last Post: May 16, 2011 08:43
by: duindain
showing 1 - 9 of 9
Posted: April 27, 2011 06:46 by duindain
Hi John,
Ive recently continued work on the project you were helping me fix a few months back, (the first post on this forum).

I am currently having an issue converting the proxy item back to the original class

In my client i get a list of remote entities which i loop through in a for loop
for(int i = 0; i < myRemoteEntities.getEntitys().size(); i++)
{
EntityInterface e = myRemoteEntities.getEntitys().get(i);
}

I can call the functions within the interface with no issues such as getOwner() //returns the ip address of the host
getID() //returns the id of the entity
anyway
I am trying to add the remote entity to the local entity list
WWPanel.getInstance().getEntityLayer().addEntity((Entity)e);

I get an exception
java.lang.ClassCastException: $Proxy2 cannot be cast to dsto.entity.Entity
 message$Proxy2 cannot be cast to dsto.entity.Entity
 local$Proxy2 cannot be cast to dsto.entity.Entity


Could you tell me how i am meant to be using the interface as the object in this instance please

Should I add a function in the interface like getEntity()?

Sorry if this is a stupid question heh
Thanks for any help
Posted: April 27, 2011 15:38 by John Catherino
The important thing to remember about the proxy mechanism is that you are dealing with objects by interface, not by type.

WWPanel.getInstance().getEntityLayer().addEntity

Should take elements of EntityInterface, rather than only objects of type Entity.

I hope that helps.

John
Posted: April 28, 2011 00:13 by duindain
I can deal with the interface 95% of the time but the line of code i mentioned
WWPanel.getInstance().getEntityLayer().addEntity((Entity)e);

is deep within the internals of the application we are using

At some point even if i add a new addEntity function that takes an interface as an argument it will have to change the interface into an actual entity

Is that not possible?
Posted: April 28, 2011 02:21 by John Catherino
The issue here, is that EntityInterface can be of many types, this is why referencing by interface is much more flexible.

Just a thought:

Is is possible for you to subclass Entity, to take an EntityInterface in its constructor, then simply route all Entity method calls onto it? (essentially a derived facade) This would then be accepted by the addEntity method.

Posted: April 28, 2011 05:17 by duindain
Ok Ive made alot of changes, Im now sharing a new interface
public interface EntityListInterface<T extends Entity> {
    public CopyOnWriteMap<EntityID, T> getCopyOnWriteMapOfEntities();
    public String getOwner();
}

This hopefully one day will make it much easier to pick up changes since its the backbone list for entities for the application
so any changes should be pretty quickly identified

CopyOnWriteMap implements Serializable as does entity and just about all the classes in it although im not sure if thats neccasary,
it was just an attempt to fix this issue.

I try to connect to servers discovered from multicast packets when one is detected i connect and eventually will be able to add the remote entities to the local entity list
networkEntityFactoryProxy dfp = new networkEntityFactoryProxy(host,port,"EntityFactory");

myRemoteEntities = dfp.getSharedNetworkEntity("local");

for(Object e : myRemoteEntities.getCopyOnWriteMapOfEntities().values())
{
//I havent yet been able to check this code since it crashes when the getCopyOnWriteMapOfEntities() returns more than 0 entities
	Entity entity = (Entity)e;
	WWPanel.getInstance().getEntityLayer().addEntity(entity);
}

networkEntityFactoryProxy
public EntityListInterface getSharedNetworkEntity(String type) throws Exception
    {
        return (EntityListInterface)TransparentItemProxy.getItem(netEntFactIntf.getNetworkEntity(type), new Class[] {EntityListInterface.class});
    }

Ive checked this and it seems to work fine unless you start pc 1 and add entities then start pc 2 then it causes an exception if you try to use the copyonwritemap features
ie
EntityListInterface inter = (EntityListInterface)TransparentItemProxy.getItem(netEntFactIntf.getNetworkEntity(type), new Class[] {EntityListInterface.class});
        System.out.println("networkEntityFactoryProxy: interface="+inter.toString());
        System.out.println("networkEntityFactoryProxy: Owner="+inter.getOwner());
        System.out.println("networkEntityFactoryProxy: Size="+inter.getCopyOnWriteMapOfEntities().size());

the last line would cause an exception

Ok so if I run both server/clients they connect and work perfectly with 0 entities in both
as soon as 1 pc has any entities added the 2nd pc will crash

I currently execute a test timer every 10 seconds which echos the current size of the entity list from the local pc and then on the next line the entity list from the remote pc
//Local entity list
System.out.println("Client Timer Event - num entities "+WWPanel.getInstance().getEntityLayer().getCopyOnWriteMapOfEntities().size());
//remote entity list
System.out.println("Client Timer Event - num remote entities "+myRemoteEntities.getCopyOnWriteMapOfEntities().size());

The second line causes an UndeclaredThrowableException as soon as there are more than 0 entities on the remote pc
Client Timer Event - num entities 0
Client Timer Event - UndeclaredThrowableException calling myRemoteEntities.getCopyOnWriteMapOfEntities().size()
java.lang.reflect.UndeclaredThrowableException
	at $Proxy1.getCopyOnWriteMapOfEntities(Unknown Source)
	at networking.cajoClient$2.actionPerformed(cajoClient.java:54)
	at javax.swing.Timer.fireActionPerformed(Timer.java:291)
	at javax.swing.Timer$DoPostEvent.run(Timer.java:221)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:642)
	at java.awt.EventQueue.access$000(EventQueue.java:85)
	at java.awt.EventQueue$1.run(EventQueue.java:603)
	at java.awt.EventQueue$1.run(EventQueue.java:601)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:612)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Caused by: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
	java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: dsto.model.Model$1
	at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:173)
	at gnu.cajo.invoke.Remote_Stub.invoke(Unknown Source)
	at gnu.cajo.invoke.Remote.invoke(Unknown Source)
	at gnu.cajo.utils.extra.TransparentItemProxy.invoke(Unknown Source)
	... 18 more
Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: dsto.model.Model$1
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1332)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
	at java.util.HashMap.readObject(HashMap.java:1030)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
	at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
	at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:155)
	... 21 more


The exception claims that the Model class wasnt Serializable but i have added implements Seriazable to that class to fix this issue with no luck
The class itself is quite large so i havent added it here yet I can if thats neccasary

Do you have any ideas what the issue could be?

Thanks for helping

Duindain

Posted: April 29, 2011 19:13 by John Catherino
If you wish to return a Map of Entity values, yes, then all of the Entity elements must be serialisable, or be derived from serialisable ancestors. However, if a Map of references to remote entities will suffice, they need not be serialisable. This is going back to the pass by-value vs. by-reference topic.

Returning a collection of references is discussed at the bottom of the design page.

I hope this helps, as always, your questions are most welcome.

John
Posted: May 05, 2011 02:15 by duindain
Hi John,
Do you have any example code using the pass by reference for collections?

I think it could be very helpful to have a good example of how to do this properly with whatever method is most efficient or correct ie using grail or just normal cajo classes

Atm the most complete example i have found was posted by someone else on the old forums the duck example im not sure if its overly complex it seems that way

Just hoping there could be a simple but complete bare bones example of pass by reference sharing of collections

Thanks for your help so far

Regards

Duindain




Posted: May 12, 2011 02:24 by duindain
Sorry Im going to rewrite this question as ive fixed some issues and run into others

Ive just changed what im sharing to this
public interface EntityCollectionInterface 
{
    public ArrayList<Object> getEntities();
    public String getOwner();
    public UUIDExtended getCurrentVersion();
}

The implementation for that class is as follows
public class sharedNetworkEntityImpl implements EntityCollectionInterface//,Observable
{
    
    public sharedNetworkEntityImpl() {}

    @Override
    public ArrayList<Object> getEntities() 
    {
        ArrayList<Object> entities = new ArrayList<Object>();
        for(Object e : ScenarioFactory.getInstance().getCurrentScenario().getCopyOnWriteMapOfEntities().values())
        {
            EntityInterface entity = (EntityInterface)e;
            entities.add(TransparentItemProxy.proxy(entity));
        }
        return entities;       
    }

    @Override
    public String getOwner() {
        return ScenarioFactory.getInstance().getCurrentScenario().getOwner();
    }
    
    @Override
    public UUIDExtended getCurrentVersion() {
        return ScenarioFactory.getInstance().getCurrentScenario().getCurrentVersion();
    }
}

The entity interface is as follows
public interface EntityInterface
{
    void setOwner(String newOwner);
    String getOwner();
    String getID();
    Entity getEntity();
}

On the clients when i want to put the remote entity into the local entitys lists i do the following
private void addRemoteEntitiesToLocalEntitys(EntityCollectionInterface myRemoteEntities)
{
for(Object e : myRemoteEntities.getEntities())
            {
EntityInterface entity = (EntityInterface)TransparentItemProxy.proxy(e);
WWPanel.getInstance().getEntityLayer().addRemoteEntity(entity.getEntity());
}
}

The issue with the above is if i move the entity on the server machine or change any of its values nothing happens on the client at all

Am i using pass by reference wrong in this instance?

Thanks for any help John.

Sorry about all the posts heh its getting close now.
Posted: May 16, 2011 08:43 by duindain
Hi John,

Im getting an error occasionally recently it seems to change between various interfaces now that ive been removing Serializable to the the transparent proxy stuff working.

How do i resolve these interface issues?

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: interface dsto.gui.Deletable is not visible from class loader
	at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353)
	at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
	at gnu.cajo.utils.extra.TransparentItemProxy.getItem(Unknown Source)
	at gnu.cajo.utils.extra.TransparentItemProxy.proxy(Unknown Source)
	at networking.sharedNetworkEntityImpl.getEntities(sharedNetworkEntityImpl.java:31)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at gnu.cajo.invoke.Remote.invoke(Unknown Source)
	at gnu.cajo.invoke.Remote.invoke(Unknown Source)
	at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
	at sun.rmi.transport.Transport$1.run(Transport.java:159)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
	at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
	at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
	at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
	at gnu.cajo.invoke.Remote_Stub.invoke(Unknown Source)
	at gnu.cajo.invoke.Remote.invoke(Unknown Source)
	at gnu.cajo.utils.extra.TransparentItemProxy.invoke(Unknown Source)
	at $Proxy1.getEntities(Unknown Source)
	at networking.UUIDEntityListListener.UUIDChanged(UUIDEntityListListener.java:74)
	at networking.UUIDEntityListListener$1.actionPerformed(UUIDEntityListListener.java:48)
	at javax.swing.Timer.fireActionPerformed(Timer.java:291)
	at javax.swing.Timer$DoPostEvent.run(Timer.java:221)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:642)
	at java.awt.EventQueue.access$000(EventQueue.java:85)
	at java.awt.EventQueue$1.run(EventQueue.java:603)
	at java.awt.EventQueue$1.run(EventQueue.java:601)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:612)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
showing 1 - 9 of 9
Replies: 8 - Last Post: May 16, 2011 08:43
by: duindain
 
 
Close
loading
Please Confirm
Close