Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All Cfn Types broken for .NET in 0.35.0 and 0.36.0 #3093

Closed
1 of 5 tasks
Assignees
Labels
bug This issue is a bug. language/dotnet Related to .NET bindings package/cfn Related to the CFN layer (L1)

Comments

@kuhnboy
Copy link

kuhnboy commented Jun 26, 2019

Note: for support questions, please first reference our documentation, then use Stackoverflow. This repository's issues are intended for feature requests and bug reports.

  • I'm submitting a ...

    • 🪲 bug report
    • 🚀 feature request
    • 📚 construct library gap
    • ☎️ security issue or vulnerability => Please see policy
    • ❓ support request => Please see note at the top of this template.
  • What is the current behavior?
    Any command to create a CfnXXX object results in an exception when running cdk synth.

  • What is the expected behavior (or behavior of feature suggested)?

  • Create a new CDK project with 0.36.0
  • Modify HelloStack to just do:
    var vpc = new CfnVPC(this, "vpc", new CfnVPCProps { CidrBlock = "10.180.0.0/16", EnableDnsHostnames = true, EnableDnsSupport = true });
  • Run cdk synth
  • Exception is thrown and error is outputted
  • What is the motivation / use case for changing the behavior or adding this feature?

  • Please tell us about your environment:

    • CDK CLI Version: 0.36.0
    • Module Version: 0.36.0
    • OS: Windows 10
    • Language: C#
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. associated pull-request, stackoverflow, gitter, etc)

Unhandled Exception: Amazon.JSII.Runtime.JsiiException: Amazon.JSII.Runtime.JsiiException: Resolution error: System.ArgumentException: Object of type 'Newtonsoft.Json.Linq.JObject' cannot be converted to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.
   at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Amazon.JSII.Runtime.CallbackExtensions.InvokeMethod(InvokeRequest request, IReferenceMap referenceMap)
   at Amazon.JSII.Runtime.CallbackExtensions.InvokeCallback(Callback callback, IReferenceMap referenceMap, IFrameworkToJsiiConverter converter, String& error).
Object creation stack:
  at new Intrinsic (C:\Users\rkuhn\AppData\Local\Temp\jsii-kernel-cSWmAu\node_modules\@aws-cdk\core\lib\private\intrinsic.js:20:44)
  at new PostResolveToken (C:\Users\rkuhn\AppData\Local\Temp\jsii-kernel-cSWmAu\node_modules\@aws-cdk\core\lib\util.js:72:9)
  at CfnVPC._toCloudFormation (C:\Users\rkuhn\AppData\Local\Temp\jsii-kernel-cSWmAu\node_modules\@aws-cdk\core\lib\cfn-resource.js:167:39)
  at node.addReference.resolve_1.findTokens (C:\Users\rkuhn\AppData\Local\Temp\jsii-kernel-cSWmAu\node_modules\@aws-cdk\core\lib\cfn-element.js:84:77)
  at Object.findTokens (C:\Users\rkuhn\AppData\Local\Temp\jsii-kernel-cSWmAu\node_modules\@aws-cdk\core\lib\private\resolve.js:125:13)
  at CfnVPC.prepare (C:\Users\rkuhn\AppData\Local\Temp\jsii-kernel-cSWmAu\node_modules\@aws-cdk\core\lib\cfn-element.js:84:49)
  at _wrapSandboxCode (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6493:51)
  at Kernel._wrapSandboxCode (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:7126:20)
  at ret._ensureSync (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6493:25)
  at Kernel._ensureSync (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:7097:20)
  at Kernel.invoke (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6492:26)
  at KernelHost.processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6186:28)
  at completeCallback (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6159:25)
  at KernelHost.callbackHandler (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6140:16)
  at KernelHost.kernel.jsii_kernel_1.Kernel.cb [as callbackHandler] (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6124:59)
  at CfnVPC.value (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6843:41)
  at Function.prepare (C:\Users\rkuhn\AppData\Local\Temp\jsii-kernel-cSWmAu\node_modules\@aws-cdk\core\lib\construct.js:91:27)
  at Function.synth (C:\Users\rkuhn\AppData\Local\Temp\jsii-kernel-cSWmAu\node_modules\@aws-cdk\core\lib\construct.js:54:14)
  at App.synth (C:\Users\rkuhn\AppData\Local\Temp\jsii-kernel-cSWmAu\node_modules\@aws-cdk\core\lib\app.js:67:52)
  at _wrapSandboxCode (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6493:51)
  at Kernel._wrapSandboxCode (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:7126:20)
  at ret._ensureSync (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6493:25)
  at Kernel._ensureSync (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:7097:20)
  at Kernel.invoke (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6492:26)
  at KernelHost.processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6186:28)
  at KernelHost.run (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6132:14)
  at processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6132:45)
  at KernelHost.processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6228:16)
  at KernelHost.run (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6132:14)
  at processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6132:45)
  at KernelHost.processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6228:16)
  at KernelHost.run (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6132:14)
  at processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6132:45)
  at KernelHost.processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6228:16)
  at KernelHost.run (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6132:14)
  at processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6132:45)
  at KernelHost.processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6228:16)
  at KernelHost.run (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6132:14)
  at processRequest (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6132:45)
  at promise.then.val (C:\Users\rkuhn\AppData\Local\Temp\yx5e5zrf.sf5\jsii-runtime.js:6213:21)
  at <anonymous>
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Deputy.DeputyBase.<InvokeMethodCore>g__GetResult|18_0[T](<>c__DisplayClass18_0`1& )
   at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeMethodCore[T](JsiiMethodAttribute methodAttribute, Object[] arguments, Func`3 beginFunc, Func`3 invokeFunc)
   at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeInstanceMethod[T](Object[] arguments, String methodName)
   at Amazon.CDK.CfnElement.Prepare()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Deputy.DeputyBase.<InvokeMethodCore>g__GetResult|18_0[T](<>c__DisplayClass18_0`1& )
   at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeMethodCore[T](JsiiMethodAttribute methodAttribute, Object[] arguments, Func`3 beginFunc, Func`3 invokeFunc)
   at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeInstanceMethod[T](Object[] arguments, String methodName)
   at HelloCdk.Program.Main(String[] args) in C:\source\foo\src\HelloCdk\Program.cs:line 19
Subprocess exited with error 3762504530
@kuhnboy kuhnboy added the needs-triage This issue or PR still needs to be triaged. label Jun 26, 2019
@kuhnboy kuhnboy changed the title All Types broken for .NET in 0.36.0 All Cfn Types broken for .NET in 0.36.0 Jun 26, 2019
@kuhnboy
Copy link
Author

kuhnboy commented Jun 26, 2019

Rolling back to each version this appears to be broken in 0.35.0 as well, but works in 0.34.0

@kuhnboy kuhnboy changed the title All Cfn Types broken for .NET in 0.36.0 All Cfn Types broken for .NET in 0.35.0 and 0.36.0 Jun 26, 2019
@eladb
Copy link
Contributor

eladb commented Jun 27, 2019

Thanks for reporting

@eladb
Copy link
Contributor

eladb commented Jun 27, 2019

Repro:

using Amazon.CDK;
using Amazon.CDK.AWS.SNS;

namespace HelloCdk
{
    public class HelloStack : Stack
    {
        public HelloStack(Construct parent, string id, IStackProps props) : base(parent, id, props)
        {
            new CfnTopic_(this, "FOO", null);
        }
    }
}

@RomainMuller
Copy link
Contributor

So I think I have gained some understanding of what is going wrong here. There's a combination of multiple factors stemming from how JSII will get values passed back-and-forth between the .NET process and the Node process.

Apparently, when objects are passed from JS to .NET by value (and not by reference), the .NET runtime deserializes those as JObject regardless of the actual type the method being invoked expects.

I am trying to come up with a minimal repro on the JSII side alone, but it is quite challenging. A full blown fix might also be quite difficult to author (but maybe I'm wrong - I'll see clearer into this once I manage to get that minimal JSII repro).

@RomainMuller RomainMuller self-assigned this Jun 27, 2019
@RomainMuller RomainMuller added bug This issue is a bug. and removed needs-triage This issue or PR still needs to be triaged. labels Jun 27, 2019
@NGL321 NGL321 added language/dotnet Related to .NET bindings package/cfn Related to the CFN layer (L1) labels Jun 27, 2019
RomainMuller added a commit that referenced this issue Jun 28, 2019
The `CfnResource#_toCloudFormation` method creates a `PostResolveToken`
with a post-processor that was not ready to handle the absence of
`Properties` on the resolved value. It is however possible that
`Properties` are missing when an object is created with the default
configuration (e.g: by `new sqs.CfnQueue(this, 'Queue');`).

This change makes the post-processor function correctly handle
`undefined` in this case.

Related #3093
RomainMuller added a commit to aws/jsii that referenced this issue Jul 1, 2019
When structures (as literal JSON blocks) get passed through a "map"
argument, a `JObject` would be passed to the method despite the declared
type on the .NET code is `IDictionary`, resulting in a crash.

This code forcefully converts `JObject` to `IDictionary<string, objetc>`
in such code paths.

Fixes aws/aws-cdk#3093
RomainMuller added a commit that referenced this issue Jul 1, 2019
The `CfnResource#_toCloudFormation` method creates a `PostResolveToken`
with a post-processor that was not ready to handle the absence of
`Properties` on the resolved value. It is however possible that
`Properties` are missing when an object is created with the default
configuration (e.g: by `new sqs.CfnQueue(this, 'Queue');`).

This change makes the post-processor function correctly handle
`undefined` in this case.

Related #3093
RomainMuller added a commit that referenced this issue Jul 1, 2019
The `CfnResource#_toCloudFormation` method creates a `PostResolveToken`
with a post-processor that was not ready to handle the absence of
`Properties` on the resolved value. It is however possible that
`Properties` are missing when an object is created with the default
configuration (e.g: by `new sqs.CfnQueue(this, 'Queue');`).

This change makes the post-processor function correctly handle
`undefined` in this case.

Related #3093
RomainMuller added a commit to aws/jsii that referenced this issue Jul 1, 2019
When structures (as literal JSON blocks) get passed through a "map"
argument, a `JObject` would be passed to the method despite the declared
type on the .NET code is `IDictionary`, resulting in a crash.

This code forcefully converts `JObject` to `IDictionary<string, objetc>`
in such code paths.

Fixes aws/aws-cdk#3093
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment