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

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

    XMLWordPrintable

    Details

    • Similar Issues:
    • Released As:
      Role Strategy 2.10

      Description

      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

        Attachments

          Activity

          jonsharpe Jon Sharpe created issue -
          jonsharpe Jon Sharpe made changes -
          Field Original Value New Value
          Description 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


          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


          jonsharpe Jon Sharpe made changes -
          Description 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


          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


          jonsharpe Jon Sharpe made changes -
          Description 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


          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 Oleg Nenashev made changes -
          Labels newbie-friendly
          oleg_nenashev Oleg Nenashev made changes -
          Assignee Oleg Nenashev [ oleg_nenashev ]
          oleg_nenashev Oleg Nenashev made changes -
          Status Open [ 1 ] In Progress [ 3 ]
          oleg_nenashev Oleg Nenashev made changes -
          Status In Progress [ 3 ] In Review [ 10005 ]
          deepansh_nagaria Deepansh Nagaria made changes -
          Assignee Deepansh Nagaria [ deepansh_nagaria ]
          oleg_nenashev Oleg Nenashev made changes -
          Status In Review [ 10005 ] Resolved [ 5 ]
          Resolution Fixed [ 1 ]
          Released As Role Strategy 2.10

            People

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

              Dates

              • Created:
                Updated:
                Resolved: