Hello all, While working on a fix for GEODE-4771 <https://issues.apache.org/jira/browse/GEODE-4771> I've came across a non-reported bug: the configure pdx command fails when no parameters are specified, even when we state in the User Guide <http://geode.apache.org/docs/guide/14/tools_modules/gfsh/command-pages/configure.html> that no parameters are mandatory to execute the command. The source code doesn't enforce any of the parameters and, as such, the resulting XmlEntity ends up being empty, so a NullPointerException is thrown when the command tries to persist the changes to the cluster configuration service:
[error 2018/03/07 11:07:48.242 GMT locator1 <RMI TCP Connection(2)-127.0.0.1> tid=0x55] error updating cluster configuration for group cluster java.lang.NullPointerException at java.io.StringReader.<init>(StringReader.java:50) at org.apache.geode.management.internal.configuration.utils.XmlUtils.createNode(XmlUtils.java:242) at org.apache.geode.management.internal.configuration.utils.XmlUtils.addNewNode(XmlUtils.java:133) at org.apache.geode.distributed.internal.ClusterConfigurationService.addXmlEntity(ClusterConfigurationService.java:204) at org.apache.geode.management.internal.cli.commands.ConfigurePDXCommand.lambda$configurePDX$0(ConfigurePDXCommand.java:131) at org.apache.geode.management.internal.cli.commands.GfshCommand.persistClusterConfiguration(GfshCommand.java:72) at org.apache.geode.management.internal.cli.commands.ConfigurePDXCommand.configurePDX(ConfigurePDXCommand.java:130) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:216) at org.apache.geode.management.internal.cli.remote.CommandExecutor.invokeCommand(CommandExecutor.java:97) at org.apache.geode.management.internal.cli.remote.CommandExecutor.execute(CommandExecutor.java:45) at org.apache.geode.management.internal.cli.remote.CommandExecutor.execute(CommandExecutor.java:39) at org.apache.geode.management.internal.cli.remote.OnlineCommandProcessor.executeCommand(OnlineCommandProcessor.java:133) at org.apache.geode.management.internal.beans.MemberMBeanBridge.processCommand(MemberMBeanBridge.java:1579) at org.apache.geode.management.internal.beans.MemberMBean.processCommand(MemberMBean.java:412) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) at com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(ConvertingMethod.java:193) at com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(ConvertingMethod.java:175) at com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(MXBeanIntrospector.java:117) at com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(MXBeanIntrospector.java:54) at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:237) at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138) at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:252) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468) at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309) at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401) at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Currently the configure pdx command only allows the user to configure the ReflectionBasedAutoSerializer class, which requires a decision on whether the check-portability flag is set as true or false. This, in turn, enforces the usage of either the portable-auto-serializable-classes(check-portability=true) or auto-serializable-classes(check-portability=false) so that the command knows exactly which of ReflectionBasedAutoSerializer should create. Within the command we could easily create an empty ReflectionBasedAutoSerializer, but it won't match any classes so it doesn't make any sense at all... The proposal is to make the flags portable-auto-serializable-classes and auto-serializable-classes mandatory, mutually exclusive. Please let me know your thoughts. Best regards. -- Ju@N