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

Invalid collections returned when element type is not a class #1196

Closed
1 of 4 tasks
RomainMuller opened this issue Jan 14, 2020 · 0 comments · Fixed by #1197
Closed
1 of 4 tasks

Invalid collections returned when element type is not a class #1196

RomainMuller opened this issue Jan 14, 2020 · 0 comments · Fixed by #1197
Assignees
Labels
bug This issue is a bug. in-progress Issue is being actively worked on. language/java Related to Java bindings module/runtime Issues affecting the `jsii-runtime` p1

Comments

@RomainMuller
Copy link
Contributor

🐛 Bug Report

Affected Languages

  • TypeScript or Javascript
  • Python
  • Java
  • .NET (C#, F#, ...)

General Information

  • JSII Version: 0.21.1 (build 9ff44cb), typescript 3.7.4
  • Platform: any

What is the problem?

When a return value is typed as a List<SomeStruct>, the Java runtime does not correctly perform the conversion to the correct Java type, and instead returns a List<JsiiObject> where the JsiiObject instances however contain all the information necessary to permit the conversion.

The runtime needs to be corrected so that it actually returns a List<SomeStruct>, or else attempting to use the contents of the list is likely to cause a ClassCastException.

It is probable the same issue would affect Map<String, SomeStruct> instances, so this has to be checked as well.

Minimal Reproduction

A minimal reproduction using the AWS CDK can be achieved:

package com.myorg;

import software.amazon.awscdk.core.*;
import software.amazon.awscdk.services.cloudwatch.Dimension;
import software.amazon.awscdk.services.cloudwatch.IMetric;
import software.amazon.awscdk.services.cloudwatch.MetricConfig;
import software.amazon.awscdk.services.lambda.Code;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;

import java.util.List;

public class CwMetricsApp {
    public static void main(final String[] args) {
        final App app = new App();
        final Stack stack = new Stack(app, "ReproStack");

        final Function funct = Function.Builder.create(stack, "Function")
                .code(Code.fromInline("export function handler() {}"))
                .handler("index.handler")
                .runtime(Runtime.NODEJS_10_X)
                .build();

        final IMetric metric = funct.metricInvocations();

        final MetricConfig config = metric.toMetricConfig();

        // This list is, in fact (and incorrectly), a List<JsiiObject>
        final List<Dimension> dimensions = config.getMetricStat().getDimensions();
        for (final Dimension dimension : dimensions) {
            System.out.println(String.format("Dimension<%s, %s>", dimension.getName(), dimension.getValue()));
        }

        app.synth();
    }
}
@RomainMuller RomainMuller added bug This issue is a bug. language/java Related to Java bindings p1 module/runtime Issues affecting the `jsii-runtime` labels Jan 14, 2020
@RomainMuller RomainMuller self-assigned this Jan 14, 2020
RomainMuller added a commit that referenced this issue Jan 14, 2020
The Java runtime for jsii used to not be able to necessarily hold the
type information necessary to correctly process the contents of
collections, as the generic information is lost.

In order to address this, introduced a new `NativeType<T>` class that is
able to carry:
1. The actual declared type of the value (via generic type parameter)
2. The raw type of the value (reified)
3. The correct JavaType to pass to Jackson to obtain the correct result

It also preserves the specific behavior around de-serialization of
`JsiiObject` sub-classes as well as jsii interfaces, correctly
requesting de-serialization as the `JsiiObject` class, and in a second
phase `transform` this into the correct value type as needed.

Introduced a new test that validates the `List<T>` and `Map<String, T>`
values received from `node` are deserialized to instances with the
appropriate content type.

Fixes #1196
@SomayaB SomayaB added the in-progress Issue is being actively worked on. label Jan 17, 2020
RomainMuller added a commit that referenced this issue Jan 20, 2020
The Java runtime for jsii used to not be able to necessarily hold the
type information necessary to correctly process the contents of
collections, as the generic information is lost.

In order to address this, introduced a new `NativeType<T>` class that is
able to carry:
1. The actual declared type of the value (via generic type parameter)
2. The raw type of the value (reified)
3. The correct JavaType to pass to Jackson to obtain the correct result

It also preserves the specific behavior around de-serialization of
`JsiiObject` sub-classes as well as jsii interfaces, correctly
requesting de-serialization as the `JsiiObject` class, and in a second
phase `transform` this into the correct value type as needed.

Introduced a new test that validates the `List<T>` and `Map<String, T>`
values received from `node` are deserialized to instances with the
appropriate content type.

Fixes #1196
@mergify mergify bot closed this as completed in #1197 Jan 27, 2020
mergify bot pushed a commit that referenced this issue Jan 27, 2020
The Java runtime for jsii used to not be able to necessarily hold the
type information necessary to correctly process the contents of
collections, as the generic information is lost.

In order to address this, introduced a new `NativeType<T>` class that is
able to carry:
1. The actual declared type of the value (via generic type parameter)
2. The raw type of the value (reified)
3. The correct JavaType to pass to Jackson to obtain the correct result

It also preserves the specific behavior around de-serialization of
`JsiiObject` sub-classes as well as jsii interfaces, correctly
requesting de-serialization as the `JsiiObject` class, and in a second
phase `transform` this into the correct value type as needed.

Introduced a new test that validates the `List<T>` and `Map<String, T>`
values received from `node` are deserialized to instances with the
appropriate content type.

Fixes #1196
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. in-progress Issue is being actively worked on. language/java Related to Java bindings module/runtime Issues affecting the `jsii-runtime` p1
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants