Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-45942

Bad error message/silent death with incorrectly setup permissions in the RoleBasedAuthorizationStrategy

    • Role Strategy 2.10

      Hiya

      Issues
      When you set the permissions incorrectly in the Groovy configuration pluggin and the permissions come over in the array as a null entry, when this goes into the ConverterImpl inside the RoleBasedAuthorizationStrategy (https://github.com/jenkinsci/role-strategy-plugin/blob/master/src/main/java/com/michelin/cio/hudson/plugins/rolestrategy/RoleBasedAuthorizationStrategy.java) (around the lines 420-427, and specifically 425) the below code is called

      for (Permission permission : role.getPermissions()) {
      writer.startNode("permission");  
      writer.setValue(permission.getId());
      writer.endNode();
      }
      

      Due to the lack of a null check the code will (for obvious reasons) error on the "permissions.getId()".
      The stack trace (at the bottom of this report) is generated.

      Options:
      a) wrap the block in:

      for (Permission permission : role.getPermissions()) {
      if(permission!=null) {
        writer.startNode("permission");
        writer.setValue(permission.getId());
        writer.endNode();
        }
      }
      

      however this may cause the undesirable effect of completing the action when it should fail

      b) throwing an error that can be understood

      for (Permission permission : role.getPermissions()) {
      if(permission==null)
         throw new NullPointerException("Cannot process the permissions as they have been incorrectly configured in the script");
      writer.startNode("permission");
      writer.setValue(permission.getId());
      writer.endNode();
      }
      

      c) place the validation on construction when the permission array is passed in

      I fully accept the defensive check should also be on the code we write, however a meaningful error message in this instance is/would be helpful to others - it took us about 1FTE day to hunt this down, and required a dig through the code to find it.

      Please note: we would "fit it" ourselves, however, as noted, due to the fact we do not actively contribute to the source code having us pick "a", "b", or "c" could cause unintended knockon issues that would be sub-optional.

      Many thanks

      Jon Sharpe

      STACK TRACE.

      java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#authorizationStrategy for class hudson.model.Hudson
      at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
      at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
      at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
      at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
      at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
      at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
      at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
      at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
      at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
      at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
      at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026)
      at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015)
      at com.thoughtworks.xstream.XStream.toXML(XStream.java:988)
      at hudson.XmlFile.write(XmlFile.java:171)
      at jenkins.model.Jenkins.save(Jenkins.java:3190)
      at hudson.model.Saveable$save.call(Unknown Source)
      at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
      at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
      at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
      at Actions.configureRole(RemoteClass:404)
      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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
      at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
      at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1218)
      at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
      at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:925)
      at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:908)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
      at RemoteClass.run(RemoteClass:1179)
      at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263)
      at groovy.lang.GroovyShell.run(GroovyShell.java:518)
      at groovy.lang.GroovyShell.run(GroovyShell.java:497)
      at hudson.cli.GroovyCommand.run(GroovyCommand.java:89)
      at hudson.cli.CLICommand.main(CLICommand.java:274)
      at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:95)
      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 hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:895)
      at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:870)
      at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:829)
      at hudson.remoting.UserRequest.perform(UserRequest.java:153)
      at hudson.remoting.UserRequest.perform(UserRequest.java:50)
      at hudson.remoting.Request$2.run(Request.java:336)
      at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
      at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:66)
      at hudson.remoting.CallableDecoratorAdapter.call(CallableDecoratorAdapter.java:18)
      at hudson.remoting.CallableDecoratorList$1.call(CallableDecoratorList.java:21)
      at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
      at java.util.concurrent.FutureTask.run(FutureTask.java:266)
      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)
      Caused by: java.lang.NullPointerException
      at com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy$ConverterImpl.marshal(RoleBasedAuthorizationStrategy.java:425)
      at hudson.util.XStream2$AssociatedConverterImpl.marshal(XStream2.java:370)
      at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
      at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
      at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
      at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
      at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
      ... 56 more

          [JENKINS-45942] Bad error message/silent death with incorrectly setup permissions in the RoleBasedAuthorizationStrategy

          Jon Sharpe created issue -
          Jon Sharpe made changes -
          Description Original: Hiya

          When you set the permissions incorrectly in the Groovy configuration pluggin and the permissions come over in the array as a null entry, when this goes into the ConverterImpl inside the RoleBasedAuthorizationStrategy (https://github.com/jenkinsci/role-strategy-plugin/blob/master/src/main/java/com/michelin/cio/hudson/plugins/rolestrategy/RoleBasedAuthorizationStrategy.java) (around the lines 420-427, and specifically 425 the below code is called

          {code}
          for (Permission permission : role.getPermissions()) {
          writer.startNode("permission");
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          Due to the lack of a null check the code will (for obvious reasons) error on the "permissions.getId()".
          The following stack trace (at the bottom of this report) is generated.

          Options:
          a) wrap the block in:
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission!=null) {
            writer.startNode("permission");
            writer.setValue(permission.getId());
            writer.endNode();
            }
          }
          {code}
          however this may cause the undesirable effect of completing the action when it should fail

          b) throwing an error that can be understood
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission==null)
             throw new NullPointerException("Cannot process the permissions as they have been incorrectly configured in the script");
          writer.startNode("permission");
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          c) place the validation on construction when the permission array is passed in

          I fully accept the defensive check should also be on the code we write, however a meaningful error message in this instance is/would be helpful to others - it took us about 1FTE day to hunt this down, and required a dig through the code to find it.

          Please note: we would "fit it" ourselves, however, as noted, due to the fact we do not actively contribute to the source code having us pick "a", "b", or "c" could cause unintended knockon issues that would be sub-optional.

          Many thanks

          Jon Sharpe


          *STACK TRACE.*

          java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#authorizationStrategy for class hudson.model.Hudson
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
                  at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
                  at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
                  at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
                  at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
                  at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
                  at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015)
                  at com.thoughtworks.xstream.XStream.toXML(XStream.java:988)
                  at hudson.XmlFile.write(XmlFile.java:171)
                  at jenkins.model.Jenkins.save(Jenkins.java:3190)
                  at hudson.model.Saveable$save.call(Unknown Source)
                  at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
                  at Actions.configureRole(RemoteClass:404)
                  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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
                  at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1218)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:925)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:908)
                  at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
                  at RemoteClass.run(RemoteClass:1179)
                  at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:518)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:497)
                  at hudson.cli.GroovyCommand.run(GroovyCommand.java:89)
                  at hudson.cli.CLICommand.main(CLICommand.java:274)
                  at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:95)
                  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 hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:895)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:870)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:829)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:153)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:50)
                  at hudson.remoting.Request$2.run(Request.java:336)
                  at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
                  at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:66)
                  at hudson.remoting.CallableDecoratorAdapter.call(CallableDecoratorAdapter.java:18)
                  at hudson.remoting.CallableDecoratorList$1.call(CallableDecoratorList.java:21)
                  at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
                  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)
          Caused by: java.lang.NullPointerException
                  at com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy$ConverterImpl.marshal(RoleBasedAuthorizationStrategy.java:425)
                  at hudson.util.XStream2$AssociatedConverterImpl.marshal(XStream2.java:370)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                 at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
                  at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
                  ... 56 more


          New: Hiya

          *Issues*
          When you set the permissions incorrectly in the Groovy configuration pluggin and the permissions come over in the array as a null entry, when this goes into the ConverterImpl inside the RoleBasedAuthorizationStrategy (https://github.com/jenkinsci/role-strategy-plugin/blob/master/src/main/java/com/michelin/cio/hudson/plugins/rolestrategy/RoleBasedAuthorizationStrategy.java) (around the lines 420-427, and specifically 425 the below code is called

          {code}
          for (Permission permission : role.getPermissions()) {
          {color:red}writer.startNode("permission");{color}
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          Due to the lack of a null check the code will (for obvious reasons) error on the "permissions.getId()".
          The stack trace (at the bottom of this report) is generated.

          *Options*:
          a) wrap the block in:
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission!=null) {
            writer.startNode("permission");
            writer.setValue(permission.getId());
            writer.endNode();
            }
          }
          {code}
          however this may cause the undesirable effect of completing the action when it should fail

          b) throwing an error that can be understood
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission==null)
             throw new NullPointerException("Cannot process the permissions as they have been incorrectly configured in the script");
          writer.startNode("permission");
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          c) place the validation on construction when the permission array is passed in

          I fully accept the defensive check should also be on the code we write, however a meaningful error message in this instance is/would be helpful to others - it took us about 1FTE day to hunt this down, and required a dig through the code to find it.

          Please note: we would "fit it" ourselves, however, as noted, due to the fact we do not actively contribute to the source code having us pick "a", "b", or "c" could cause unintended knockon issues that would be sub-optional.

          Many thanks

          Jon Sharpe


          *STACK TRACE.*

          java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#authorizationStrategy for class hudson.model.Hudson
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
                  at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
                  at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
                  at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
                  at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
                  at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
                  at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015)
                  at com.thoughtworks.xstream.XStream.toXML(XStream.java:988)
                  at hudson.XmlFile.write(XmlFile.java:171)
                  at jenkins.model.Jenkins.save(Jenkins.java:3190)
                  at hudson.model.Saveable$save.call(Unknown Source)
                  at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
                  at Actions.configureRole(RemoteClass:404)
                  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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
                  at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1218)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:925)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:908)
                  at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
                  at RemoteClass.run(RemoteClass:1179)
                  at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:518)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:497)
                  at hudson.cli.GroovyCommand.run(GroovyCommand.java:89)
                  at hudson.cli.CLICommand.main(CLICommand.java:274)
                  at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:95)
                  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 hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:895)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:870)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:829)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:153)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:50)
                  at hudson.remoting.Request$2.run(Request.java:336)
                  at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
                  at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:66)
                  at hudson.remoting.CallableDecoratorAdapter.call(CallableDecoratorAdapter.java:18)
                  at hudson.remoting.CallableDecoratorList$1.call(CallableDecoratorList.java:21)
                  at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
                  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)
          Caused by: java.lang.NullPointerException
                  at com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy$ConverterImpl.marshal(RoleBasedAuthorizationStrategy.java:425)
                  at hudson.util.XStream2$AssociatedConverterImpl.marshal(XStream2.java:370)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                 at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
                  at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
                  ... 56 more


          Jon Sharpe made changes -
          Description Original: Hiya

          *Issues*
          When you set the permissions incorrectly in the Groovy configuration pluggin and the permissions come over in the array as a null entry, when this goes into the ConverterImpl inside the RoleBasedAuthorizationStrategy (https://github.com/jenkinsci/role-strategy-plugin/blob/master/src/main/java/com/michelin/cio/hudson/plugins/rolestrategy/RoleBasedAuthorizationStrategy.java) (around the lines 420-427, and specifically 425 the below code is called

          {code}
          for (Permission permission : role.getPermissions()) {
          {color:red}writer.startNode("permission");{color}
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          Due to the lack of a null check the code will (for obvious reasons) error on the "permissions.getId()".
          The stack trace (at the bottom of this report) is generated.

          *Options*:
          a) wrap the block in:
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission!=null) {
            writer.startNode("permission");
            writer.setValue(permission.getId());
            writer.endNode();
            }
          }
          {code}
          however this may cause the undesirable effect of completing the action when it should fail

          b) throwing an error that can be understood
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission==null)
             throw new NullPointerException("Cannot process the permissions as they have been incorrectly configured in the script");
          writer.startNode("permission");
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          c) place the validation on construction when the permission array is passed in

          I fully accept the defensive check should also be on the code we write, however a meaningful error message in this instance is/would be helpful to others - it took us about 1FTE day to hunt this down, and required a dig through the code to find it.

          Please note: we would "fit it" ourselves, however, as noted, due to the fact we do not actively contribute to the source code having us pick "a", "b", or "c" could cause unintended knockon issues that would be sub-optional.

          Many thanks

          Jon Sharpe


          *STACK TRACE.*

          java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#authorizationStrategy for class hudson.model.Hudson
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
                  at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
                  at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
                  at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
                  at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
                  at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
                  at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015)
                  at com.thoughtworks.xstream.XStream.toXML(XStream.java:988)
                  at hudson.XmlFile.write(XmlFile.java:171)
                  at jenkins.model.Jenkins.save(Jenkins.java:3190)
                  at hudson.model.Saveable$save.call(Unknown Source)
                  at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
                  at Actions.configureRole(RemoteClass:404)
                  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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
                  at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1218)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:925)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:908)
                  at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
                  at RemoteClass.run(RemoteClass:1179)
                  at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:518)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:497)
                  at hudson.cli.GroovyCommand.run(GroovyCommand.java:89)
                  at hudson.cli.CLICommand.main(CLICommand.java:274)
                  at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:95)
                  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 hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:895)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:870)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:829)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:153)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:50)
                  at hudson.remoting.Request$2.run(Request.java:336)
                  at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
                  at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:66)
                  at hudson.remoting.CallableDecoratorAdapter.call(CallableDecoratorAdapter.java:18)
                  at hudson.remoting.CallableDecoratorList$1.call(CallableDecoratorList.java:21)
                  at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
                  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)
          Caused by: java.lang.NullPointerException
                  at com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy$ConverterImpl.marshal(RoleBasedAuthorizationStrategy.java:425)
                  at hudson.util.XStream2$AssociatedConverterImpl.marshal(XStream2.java:370)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                 at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
                  at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
                  ... 56 more


          New: Hiya

          *Issues*
          When you set the permissions incorrectly in the Groovy configuration pluggin and the permissions come over in the array as a null entry, when this goes into the ConverterImpl inside the RoleBasedAuthorizationStrategy (https://github.com/jenkinsci/role-strategy-plugin/blob/master/src/main/java/com/michelin/cio/hudson/plugins/rolestrategy/RoleBasedAuthorizationStrategy.java) (around the lines 420-427, and specifically 425 the below code is called

          {code}
          for (Permission permission : role.getPermissions()) {
          writer.startNode("permission");
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          Due to the lack of a null check the code will (for obvious reasons) error on the "permissions.getId()".
          The stack trace (at the bottom of this report) is generated.

          *Options*:
          a) wrap the block in:
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission!=null) {
            writer.startNode("permission");
            writer.setValue(permission.getId());
            writer.endNode();
            }
          }
          {code}
          however this may cause the undesirable effect of completing the action when it should fail

          b) throwing an error that can be understood
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission==null)
             throw new NullPointerException("Cannot process the permissions as they have been incorrectly configured in the script");
          writer.startNode("permission");
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          c) place the validation on construction when the permission array is passed in

          I fully accept the defensive check should also be on the code we write, however a meaningful error message in this instance is/would be helpful to others - it took us about 1FTE day to hunt this down, and required a dig through the code to find it.

          Please note: we would "fit it" ourselves, however, as noted, due to the fact we do not actively contribute to the source code having us pick "a", "b", or "c" could cause unintended knockon issues that would be sub-optional.

          Many thanks

          Jon Sharpe


          *STACK TRACE.*

          java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#authorizationStrategy for class hudson.model.Hudson
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
                  at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
                  at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
                  at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
                  at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
                  at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
                  at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015)
                  at com.thoughtworks.xstream.XStream.toXML(XStream.java:988)
                  at hudson.XmlFile.write(XmlFile.java:171)
                  at jenkins.model.Jenkins.save(Jenkins.java:3190)
                  at hudson.model.Saveable$save.call(Unknown Source)
                  at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
                  at Actions.configureRole(RemoteClass:404)
                  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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
                  at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1218)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:925)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:908)
                  at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
                  at RemoteClass.run(RemoteClass:1179)
                  at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:518)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:497)
                  at hudson.cli.GroovyCommand.run(GroovyCommand.java:89)
                  at hudson.cli.CLICommand.main(CLICommand.java:274)
                  at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:95)
                  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 hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:895)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:870)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:829)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:153)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:50)
                  at hudson.remoting.Request$2.run(Request.java:336)
                  at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
                  at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:66)
                  at hudson.remoting.CallableDecoratorAdapter.call(CallableDecoratorAdapter.java:18)
                  at hudson.remoting.CallableDecoratorList$1.call(CallableDecoratorList.java:21)
                  at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
                  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)
          Caused by: java.lang.NullPointerException
                  at com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy$ConverterImpl.marshal(RoleBasedAuthorizationStrategy.java:425)
                  at hudson.util.XStream2$AssociatedConverterImpl.marshal(XStream2.java:370)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                 at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
                  at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
                  ... 56 more


          Jon Sharpe made changes -
          Description Original: Hiya

          *Issues*
          When you set the permissions incorrectly in the Groovy configuration pluggin and the permissions come over in the array as a null entry, when this goes into the ConverterImpl inside the RoleBasedAuthorizationStrategy (https://github.com/jenkinsci/role-strategy-plugin/blob/master/src/main/java/com/michelin/cio/hudson/plugins/rolestrategy/RoleBasedAuthorizationStrategy.java) (around the lines 420-427, and specifically 425 the below code is called

          {code}
          for (Permission permission : role.getPermissions()) {
          writer.startNode("permission");
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          Due to the lack of a null check the code will (for obvious reasons) error on the "permissions.getId()".
          The stack trace (at the bottom of this report) is generated.

          *Options*:
          a) wrap the block in:
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission!=null) {
            writer.startNode("permission");
            writer.setValue(permission.getId());
            writer.endNode();
            }
          }
          {code}
          however this may cause the undesirable effect of completing the action when it should fail

          b) throwing an error that can be understood
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission==null)
             throw new NullPointerException("Cannot process the permissions as they have been incorrectly configured in the script");
          writer.startNode("permission");
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          c) place the validation on construction when the permission array is passed in

          I fully accept the defensive check should also be on the code we write, however a meaningful error message in this instance is/would be helpful to others - it took us about 1FTE day to hunt this down, and required a dig through the code to find it.

          Please note: we would "fit it" ourselves, however, as noted, due to the fact we do not actively contribute to the source code having us pick "a", "b", or "c" could cause unintended knockon issues that would be sub-optional.

          Many thanks

          Jon Sharpe


          *STACK TRACE.*

          java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#authorizationStrategy for class hudson.model.Hudson
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
                  at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
                  at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
                  at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
                  at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
                  at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
                  at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015)
                  at com.thoughtworks.xstream.XStream.toXML(XStream.java:988)
                  at hudson.XmlFile.write(XmlFile.java:171)
                  at jenkins.model.Jenkins.save(Jenkins.java:3190)
                  at hudson.model.Saveable$save.call(Unknown Source)
                  at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
                  at Actions.configureRole(RemoteClass:404)
                  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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
                  at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1218)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:925)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:908)
                  at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
                  at RemoteClass.run(RemoteClass:1179)
                  at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:518)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:497)
                  at hudson.cli.GroovyCommand.run(GroovyCommand.java:89)
                  at hudson.cli.CLICommand.main(CLICommand.java:274)
                  at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:95)
                  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 hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:895)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:870)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:829)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:153)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:50)
                  at hudson.remoting.Request$2.run(Request.java:336)
                  at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
                  at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:66)
                  at hudson.remoting.CallableDecoratorAdapter.call(CallableDecoratorAdapter.java:18)
                  at hudson.remoting.CallableDecoratorList$1.call(CallableDecoratorList.java:21)
                  at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
                  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)
          Caused by: java.lang.NullPointerException
                  at com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy$ConverterImpl.marshal(RoleBasedAuthorizationStrategy.java:425)
                  at hudson.util.XStream2$AssociatedConverterImpl.marshal(XStream2.java:370)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                 at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
                  at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
                  ... 56 more


          New: Hiya

          *Issues*
          When you set the permissions incorrectly in the Groovy configuration pluggin and the permissions come over in the array as a null entry, when this goes into the ConverterImpl inside the RoleBasedAuthorizationStrategy (https://github.com/jenkinsci/role-strategy-plugin/blob/master/src/main/java/com/michelin/cio/hudson/plugins/rolestrategy/RoleBasedAuthorizationStrategy.java) (around the lines 420-427, and specifically 425) the below code is called

          {code}
          for (Permission permission : role.getPermissions()) {
          writer.startNode("permission");
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          Due to the lack of a null check the code will (for obvious reasons) error on the "permissions.getId()".
          The stack trace (at the bottom of this report) is generated.

          *Options*:
          a) wrap the block in:
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission!=null) {
            writer.startNode("permission");
            writer.setValue(permission.getId());
            writer.endNode();
            }
          }
          {code}
          however this may cause the undesirable effect of completing the action when it should fail

          b) throwing an error that can be understood
          {code}
          for (Permission permission : role.getPermissions()) {
          if(permission==null)
             throw new NullPointerException("Cannot process the permissions as they have been incorrectly configured in the script");
          writer.startNode("permission");
          writer.setValue(permission.getId());
          writer.endNode();
          }
          {code}

          c) place the validation on construction when the permission array is passed in

          I fully accept the defensive check should also be on the code we write, however a meaningful error message in this instance is/would be helpful to others - it took us about 1FTE day to hunt this down, and required a dig through the code to find it.

          Please note: we would "fit it" ourselves, however, as noted, due to the fact we do not actively contribute to the source code having us pick "a", "b", or "c" could cause unintended knockon issues that would be sub-optional.

          Many thanks

          Jon Sharpe


          *STACK TRACE.*

          java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#authorizationStrategy for class hudson.model.Hudson
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
                  at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
                  at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
                  at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
                  at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
                  at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
                  at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026)
                  at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015)
                  at com.thoughtworks.xstream.XStream.toXML(XStream.java:988)
                  at hudson.XmlFile.write(XmlFile.java:171)
                  at jenkins.model.Jenkins.save(Jenkins.java:3190)
                  at hudson.model.Saveable$save.call(Unknown Source)
                  at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
                  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
                  at Actions.configureRole(RemoteClass:404)
                  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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
                  at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1218)
                  at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:925)
                  at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:908)
                  at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
                  at RemoteClass.run(RemoteClass:1179)
                  at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:518)
                  at groovy.lang.GroovyShell.run(GroovyShell.java:497)
                  at hudson.cli.GroovyCommand.run(GroovyCommand.java:89)
                  at hudson.cli.CLICommand.main(CLICommand.java:274)
                  at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:95)
                  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 hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:895)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:870)
                  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:829)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:153)
                  at hudson.remoting.UserRequest.perform(UserRequest.java:50)
                  at hudson.remoting.Request$2.run(Request.java:336)
                  at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
                  at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:66)
                  at hudson.remoting.CallableDecoratorAdapter.call(CallableDecoratorAdapter.java:18)
                  at hudson.remoting.CallableDecoratorList$1.call(CallableDecoratorList.java:21)
                  at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
                  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)
          Caused by: java.lang.NullPointerException
                  at com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy$ConverterImpl.marshal(RoleBasedAuthorizationStrategy.java:425)
                  at hudson.util.XStream2$AssociatedConverterImpl.marshal(XStream2.java:370)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
                 at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
                  at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
                  at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
                  at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
                  ... 56 more


          Oleg Nenashev made changes -
          Labels New: newbie-friendly
          Oleg Nenashev made changes -
          Assignee Original: Oleg Nenashev [ oleg_nenashev ]
          Oleg Nenashev made changes -
          Status Original: Open [ 1 ] New: In Progress [ 3 ]
          Oleg Nenashev made changes -
          Status Original: In Progress [ 3 ] New: In Review [ 10005 ]
          Deepansh Nagaria made changes -
          Assignee New: Deepansh Nagaria [ deepansh_nagaria ]
          Oleg Nenashev made changes -
          Released As New: Role Strategy 2.10
          Resolution New: Fixed [ 1 ]
          Status Original: In Review [ 10005 ] New: Resolved [ 5 ]

            deepansh_nagaria Deepansh Nagaria
            jonsharpe Jon Sharpe
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: