[SOLVED] IllegalAccessException when using "protected" no-arg constructor for PersistentComponent [Zay-ES]

Hi

Using a “protected” no-arg constructor for my PersistentComponents I get an IllegalAccessException when requesting the component from EntityData.

It would be nice to add support for “protected” no-arg constructors in the Zay-ES persistence module.

Exception stack trace:

17:18:01,690 ERROR [KernelAdapter] Unhandled error, endpoint:NioEndpoint[1, java.nio.channels.SocketChannel[connected local=/127.0.0.1:4273 remote=/127.0.0.1:42606]], context:GetEntitySetMessage[2, null, [class com.dalwiestudio.rpg.core.es.ViewType, class com.dalwiestudio.rpg.core.es.ModelInfo, class com.dalwiestudio.rpg.physics.es.BodyPosition]]
java.lang.RuntimeException: Error executing:public void com.simsilica.es.server.HostedEntityData.getEntitySet(com.jme3.network.HostedConnection,com.simsilica.es.net.GetEntitySetMessage)
	at com.simsilica.es.net.AbstractMessageDelegator.messageReceived(AbstractMessageDelegator.java:238) ~[zay-es-net-1.4.3.jar:?]
	at com.simsilica.es.net.AbstractMessageDelegator.messageReceived(AbstractMessageDelegator.java:59) ~[zay-es-net-1.4.3.jar:?]
	at com.jme3.network.base.MessageListenerRegistry.messageReceived(MessageListenerRegistry.java:81) ~[jme3-networking-3.4.0-beta4.jar:3.4.0-beta4]
	at com.jme3.network.base.DefaultServer.dispatch(DefaultServer.java:343) ~[jme3-networking-3.4.0-beta4.jar:3.4.0-beta4]
	at com.jme3.network.base.DefaultServer$Redispatch.messageReceived(DefaultServer.java:676) ~[jme3-networking-3.4.0-beta4.jar:3.4.0-beta4]
	at com.jme3.network.base.DefaultServer$Redispatch.messageReceived(DefaultServer.java:671) ~[jme3-networking-3.4.0-beta4.jar:3.4.0-beta4]
	at com.jme3.network.base.KernelAdapter.dispatch(KernelAdapter.java:190) [jme3-networking-3.4.0-beta4.jar:3.4.0-beta4]
	at com.jme3.network.base.KernelAdapter.createAndDispatch(KernelAdapter.java:243) [jme3-networking-3.4.0-beta4.jar:3.4.0-beta4]
	at com.jme3.network.base.KernelAdapter.run(KernelAdapter.java:287) [jme3-networking-3.4.0-beta4.jar:3.4.0-beta4]
Caused by: java.lang.RuntimeException: Error in table mapping
	at com.simsilica.es.sql.ComponentTable.getComponent(ComponentTable.java:325) ~[zay-es-1.3.2.jar:?]
	at com.simsilica.es.sql.SqlComponentHandler.getComponent(SqlComponentHandler.java:94) ~[zay-es-1.3.2.jar:?]
	at com.simsilica.es.base.DefaultEntityData.getComponent(DefaultEntityData.java:163) ~[zay-es-1.3.2.jar:?]
	at com.simsilica.es.server.EntityDataWrapper.getComponent(EntityDataWrapper.java:139) ~[zay-es-net-1.4.3.jar:?]
	at com.simsilica.es.base.DefaultEntitySet.loadEntities(DefaultEntitySet.java:148) ~[zay-es-1.3.2.jar:?]
	at com.simsilica.es.server.EntityDataWrapper$LocalEntitySet.loadEntities(EntityDataWrapper.java:354) ~[zay-es-net-1.4.3.jar:?]
	at com.simsilica.es.server.EntityDataWrapper.getEntities(EntityDataWrapper.java:255) ~[zay-es-net-1.4.3.jar:?]
	at com.simsilica.es.server.HostedEntityData.getEntitySet(HostedEntityData.java:272) ~[zay-es-net-1.4.3.jar:?]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[?:?]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[?:?]
	at com.simsilica.es.net.AbstractMessageDelegator.messageReceived(AbstractMessageDelegator.java:231) ~[zay-es-net-1.4.3.jar:?]
	... 8 more
Caused by: java.lang.IllegalAccessException: class com.simsilica.es.sql.ComponentTable cannot access a member of class com.dalwiestudio.rpg.core.es.ViewType with modifiers "protected"
	at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:385) ~[?:?]
	at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:687) ~[?:?]
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:489) ~[?:?]
	at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128) ~[?:?]
	at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:350) ~[?:?]
	at java.base/java.lang.Class.newInstance(Class.java:642) ~[?:?]
	at com.simsilica.es.sql.ComponentTable.getComponent(ComponentTable.java:314) ~[zay-es-1.3.2.jar:?]
	at com.simsilica.es.sql.SqlComponentHandler.getComponent(SqlComponentHandler.java:94) ~[zay-es-1.3.2.jar:?]
	at com.simsilica.es.base.DefaultEntityData.getComponent(DefaultEntityData.java:163) ~[zay-es-1.3.2.jar:?]
	at com.simsilica.es.server.EntityDataWrapper.getComponent(EntityDataWrapper.java:139) ~[zay-es-net-1.4.3.jar:?]
	at com.simsilica.es.base.DefaultEntitySet.loadEntities(DefaultEntitySet.java:148) ~[zay-es-1.3.2.jar:?]
	at com.simsilica.es.server.EntityDataWrapper$LocalEntitySet.loadEntities(EntityDataWrapper.java:354) ~[zay-es-net-1.4.3.jar:?]
	at com.simsilica.es.server.EntityDataWrapper.getEntities(EntityDataWrapper.java:255) ~[zay-es-net-1.4.3.jar:?]
	at com.simsilica.es.server.HostedEntityData.getEntitySet(HostedEntityData.java:272) ~[zay-es-net-1.4.3.jar:?]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[?:?]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[?:?]
	at com.simsilica.es.net.AbstractMessageDelegator.messageReceived(AbstractMessageDelegator.java:231) ~[zay-es-net-1.4.3.jar:?]
	... 8 more

Regards

1 Like

I solved it in this commit

In my fix, I am getting the component class no-arg constructor once and use reflection to make it accessible and cache it, then reuse it every time in getComponent() method and components( SqlSession session ) method to make a new instance.

The reason I am caching constructor and reusing it is that I thought doing

Constructor constructor = type.getDeclaredConstructor();
constructor.setAccessible(true);

everytime, might have an overhead (?) my question is, is this overhead negligible?

It’s good to cache it. I will take a look at your patch soon.