ballerina-lang icon indicating copy to clipboard operation
ballerina-lang copied to clipboard

Invocations with xml-typed parameters within a query expression crashes during code generation

Open IMS94 opened this issue 3 years ago • 6 comments

Description: Following service crashes when we run it with bal run (even without sending a request to the get method)

import ballerina/io;
import ballerina/xmldata;
import ballerina/http;

type Order record {
    string id;
    Product[] items;
};

type Product record {|
    string id;
    string name;
    Price price;
    int quantity;
|};

type Price record {|
    decimal amount;
    string currency;
|};

service / on new http:Listener(9090) {

    resource function post greeting() returns http:Ok|http:InternalServerError|error {
        xml payload = check io:fileReadXml("sample.xml");

        xml items = payload/*;
        // json converted = items.toJson();

        Order[] orders = from xml item in items
            let Order o = check xmldata:fromXml(item, Order)
            select o;
        io:println(orders);

        return <http:Ok>{};
    }
}

Here's the logs:

imesha@imesha:~/Documents/WSO2/Ballerina/Projects/test_project$ bal run /home/imesha/Documents/WSO2/Ballerina/Projects/test_project/test2.bal 
Compiling source
        test2.bal
WARNING [test2.bal:(31:33,31:69)] usage of construct 'ballerina/xmldata:2.3.0:toRecord' is deprecated

Running executable

[2022-08-17 15:02:58,882] SEVERE {b7a.log.crash} - Bad type on operand stack
Exception Details:
  Location:
    test2.$streamLambda$_1(Lio/ballerina/runtime/internal/scheduling/Strand;Lio/ballerina/runtime/internal/values/MapValue;Z)Ljava/lang/Object; @177: invokestatic
  Reason:
    Type 'java/lang/Object' (current frame, stack[1]) is not assignable to 'io/ballerina/runtime/internal/values/XmlValue'
  Current Frame:
    bci: @177
    flags: { }
    locals: { 'io/ballerina/runtime/internal/scheduling/Strand', 'io/ballerina/runtime/internal/values/MapValue', integer, 'java/lang/Object', 'java/lang/Object', 'io/ballerina/runtime/api/values/BString', 'io/ballerina/runtime/internal/values/MapValue', 'io/ballerina/runtime/internal/values/MapValue', 'java/lang/Object', integer, 'io/ballerina/runtime/internal/values/TypedescValue', 'java/lang/Object', 'io/ballerina/runtime/internal/values/ErrorValue', 'java/lang/Object', integer, null, null }
    stack: { 'io/ballerina/runtime/internal/scheduling/Strand', 'java/lang/Object', integer, integer, integer, 'io/ballerina/runtime/internal/values/TypedescValue', integer }
  Bytecode:
    0000000: 2ab4 0011 9900 07b8 0017 bf01 4e01 3a04
    0000010: 013a 0501 3a06 013a 0701 3a08 0336 0901
    0000020: 3a0a 013a 0b01 3a0c 013a 0d03 360e 013a
    0000030: 0f01 3a10 2ab4 001b 9d01 0415 0eab 0000
    0000040: 0000 0166 0000 0007 0000 0000 0000 0043
    0000050: 0000 0001 0000 0066 0000 0002 0000 009c
    0000060: 0000 0003 0000 00b6 0000 0004 0000 00cf
    0000070: 0000 0005 0000 00ef 0000 0006 0000 00f7
    0000080: 1100 0036 0eb2 00a2 3a05 2bc0 002a 1905
    0000090: b900 9f02 003a 0419 044e 12c1 3609 b200
    00000a0: c43a 0a11 0001 360e 2a2d 0415 0904 190a
    00000b0: 04b8 00ca 3a0b 2ab6 005d 9900 0e12 cc3a
    00000c0: 0f12 613a 10a7 00de a700 0319 0b3a 0819
    00000d0: 08b2 00cf b800 d536 0911 0002 360e 1509
    00000e0: 9d00 06a7 0018 1908 b200 cfb8 00d9 c000
    00000f0: 2a3a 0711 0003 360e a700 1c19 08b2 00dd
    0000100: b800 d9c0 00df 3a0c 190c 3a0d 1100 0436
    0000110: 0ea7 0023 1907 3a06 1906 3a04 b200 e23a
    0000120: 052b 1905 1904 b800 a82b 3a0d 1100 0536
    0000130: 0ea7 0003 1100 0636 0e19 0db0 2a59 b400
    0000140: 1b04 64b5 001b 2ab4 0065 b600 6bc0 00e4
    0000150: 59b4 00e5 3a0d 59b4 00e6 4c59 b400 e73d
    0000160: 59b4 00e8 4e59 b400 e93a 0459 b400 ea3a
    0000170: 0559 b400 eb3a 0659 b400 ee3a 0759 b400
    0000180: f13a 0859 b400 f436 0959 b400 f73a 0a59
    0000190: b400 fa3a 0b59 b400 fe3a 0cb4 00ff 360e
    00001a0: a7fe 9bbb 00e4 59b7 0100 5919 0db5 00e5
    00001b0: 592b b500 e659 1cb5 00e7 592d b500 e859
    00001c0: 1904 b500 e959 1905 b500 ea59 1906 b500
    00001d0: eb59 1907 b500 ee59 1908 b500 f159 1509
    00001e0: b500 f459 190a c000 4fb5 00f7 5919 0bb5
    00001f0: 00fa 5919 0cb5 00fe 5915 0eb5 00ff 5919
    0000200: 0fb5 0101 5919 10b5 0102 3a11 2ab4 0065
    0000210: 1911 b600 9157 2a59 b400 1b04 60b5 001b
    0000220: 190d b0                                
  Stackmap Table:
    same_frame(@11)
    full_frame(@59,{Object[#13],Object[#42],Integer,Object[#4],Object[#4],Object[#149],Object[#42],Object[#42],Object[#4],Integer,Object[#79],Object[#4],Object[#223],Object[#4],Integer,Null,Null},{})
    same_frame_extended(@128)
    same_frame(@163)
    same_frame(@200)
    same_frame(@203)
    same_frame(@217)
    same_frame(@230)
    same_frame(@243)
    same_frame(@251)
    same_frame(@268)
    same_frame(@276)
    same_frame(@300)
    same_frame(@308)
    full_frame(@316,{Object[#13],Object[#42],Integer,Null,Null,Null,Null,Null,Null,Integer,Null,Null,Null,Null,Integer,Null,Null},{})
    full_frame(@419,{Object[#13],Object[#42],Integer,Object[#4],Object[#4],Object[#149],Object[#42],Object[#42],Object[#4],Integer,Object[#79],Object[#4],Object[#223],Object[#4],Integer,Object[#151],Object[#151]},{})
 
java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    test2.$streamLambda$_1(Lio/ballerina/runtime/internal/scheduling/Strand;Lio/ballerina/runtime/internal/values/MapValue;Z)Ljava/lang/Object; @177: invokestatic
  Reason:
    Type 'java/lang/Object' (current frame, stack[1]) is not assignable to 'io/ballerina/runtime/internal/values/XmlValue'
  Current Frame:
    bci: @177
    flags: { }
    locals: { 'io/ballerina/runtime/internal/scheduling/Strand', 'io/ballerina/runtime/internal/values/MapValue', integer, 'java/lang/Object', 'java/lang/Object', 'io/ballerina/runtime/api/values/BString', 'io/ballerina/runtime/internal/values/MapValue', 'io/ballerina/runtime/internal/values/MapValue', 'java/lang/Object', integer, 'io/ballerina/runtime/internal/values/TypedescValue', 'java/lang/Object', 'io/ballerina/runtime/internal/values/ErrorValue', 'java/lang/Object', integer, null, null }
    stack: { 'io/ballerina/runtime/internal/scheduling/Strand', 'java/lang/Object', integer, integer, integer, 'io/ballerina/runtime/internal/values/TypedescValue', integer }
  Bytecode:
    0000000: 2ab4 0011 9900 07b8 0017 bf01 4e01 3a04
    0000010: 013a 0501 3a06 013a 0701 3a08 0336 0901
    0000020: 3a0a 013a 0b01 3a0c 013a 0d03 360e 013a
    0000030: 0f01 3a10 2ab4 001b 9d01 0415 0eab 0000
    0000040: 0000 0166 0000 0007 0000 0000 0000 0043
    0000050: 0000 0001 0000 0066 0000 0002 0000 009c
    0000060: 0000 0003 0000 00b6 0000 0004 0000 00cf
    0000070: 0000 0005 0000 00ef 0000 0006 0000 00f7
    0000080: 1100 0036 0eb2 00a2 3a05 2bc0 002a 1905
    0000090: b900 9f02 003a 0419 044e 12c1 3609 b200
    00000a0: c43a 0a11 0001 360e 2a2d 0415 0904 190a
    00000b0: 04b8 00ca 3a0b 2ab6 005d 9900 0e12 cc3a
    00000c0: 0f12 613a 10a7 00de a700 0319 0b3a 0819
    00000d0: 08b2 00cf b800 d536 0911 0002 360e 1509
    00000e0: 9d00 06a7 0018 1908 b200 cfb8 00d9 c000
    00000f0: 2a3a 0711 0003 360e a700 1c19 08b2 00dd
    0000100: b800 d9c0 00df 3a0c 190c 3a0d 1100 0436
    0000110: 0ea7 0023 1907 3a06 1906 3a04 b200 e23a
    0000120: 052b 1905 1904 b800 a82b 3a0d 1100 0536
    0000130: 0ea7 0003 1100 0636 0e19 0db0 2a59 b400
    0000140: 1b04 64b5 001b 2ab4 0065 b600 6bc0 00e4
    0000150: 59b4 00e5 3a0d 59b4 00e6 4c59 b400 e73d
    0000160: 59b4 00e8 4e59 b400 e93a 0459 b400 ea3a
    0000170: 0559 b400 eb3a 0659 b400 ee3a 0759 b400
    0000180: f13a 0859 b400 f436 0959 b400 f73a 0a59
    0000190: b400 fa3a 0b59 b400 fe3a 0cb4 00ff 360e
    00001a0: a7fe 9bbb 00e4 59b7 0100 5919 0db5 00e5
    00001b0: 592b b500 e659 1cb5 00e7 592d b500 e859
    00001c0: 1904 b500 e959 1905 b500 ea59 1906 b500
    00001d0: eb59 1907 b500 ee59 1908 b500 f159 1509
    00001e0: b500 f459 190a c000 4fb5 00f7 5919 0bb5
    00001f0: 00fa 5919 0cb5 00fe 5915 0eb5 00ff 5919
    0000200: 0fb5 0101 5919 10b5 0102 3a11 2ab4 0065
    0000210: 1911 b600 9157 2a59 b400 1b04 60b5 001b
    0000220: 190d b0                                
  Stackmap Table:
    same_frame(@11)
    full_frame(@59,{Object[#13],Object[#42],Integer,Object[#4],Object[#4],Object[#149],Object[#42],Object[#42],Object[#4],Integer,Object[#79],Object[#4],Object[#223],Object[#4],Integer,Null,Null},{})
    same_frame_extended(@128)
    same_frame(@163)
    same_frame(@200)
    same_frame(@203)
    same_frame(@217)
    same_frame(@230)
    same_frame(@243)
    same_frame(@251)
    same_frame(@268)
    same_frame(@276)
    same_frame(@300)
    same_frame(@308)
    full_frame(@316,{Object[#13],Object[#42],Integer,Null,Null,Null,Null,Null,Null,Integer,Null,Null,Null,Null,Integer,Null,Null},{})
    full_frame(@419,{Object[#13],Object[#42],Integer,Object[#4],Object[#4],Object[#149],Object[#42],Object[#42],Object[#4],Integer,Object[#79],Object[#4],Object[#223],Object[#4],Integer,Object[#151],Object[#151]},{})

        at $_init.$annot_func$_0$lambda0$(.)
        at io.ballerina.runtime.internal.values.FPValue.call(FPValue.java:65)
        at io.ballerina.runtime.internal.AnnotationUtils.processObjectCtorAnnotations(AnnotationUtils.java:89)
        at $$$.$gen$$0046$0046$0060init$00620(.:22)
        at $_init.$gen$$0046$0060init$0062(.:0)
        at $_init.$moduleInit(.)
        at $_init.$lambda$$moduleInit$(.)
        at io.ballerina.runtime.internal.scheduling.SchedulerItem.execute(Scheduler.java:569)
        at io.ballerina.runtime.internal.scheduling.Scheduler.run(Scheduler.java:303)
        at io.ballerina.runtime.internal.scheduling.Scheduler.runSafely(Scheduler.java:270)
        at java.base/java.lang.Thread.run(Thread.java:829)

Steps to reproduce: See description

Affected Versions: 2201.1.1 (Choreo) 220.2.0 RC1

IMS94 avatar Aug 17 '22 09:08 IMS94

This seems to be a bug related to query expressions; not services. The same issue is reproducible with

import ballerina/io;
import ballerina/xmldata;
// import ballerina/http;

type Order record {
    string id;
    Product[] items;
};

type Product record {|
    string id;
    string name;
    Price price;
    int quantity;
|};

type Price record {|
    decimal amount;
    string currency;
|};

public function main() returns error? {
    xml payload = check io:fileReadXml("sample.xml");

    xml items = payload/*;

    _ = from xml item in items
        let Order o = check xmldata:fromXml(item, Order)
        select o;
}

pcnfernando avatar Aug 17 '22 12:08 pcnfernando

This is related to a known issue while closure resolving and it's tracked through https://github.com/ballerina-platform/ballerina-lang/issues/32710. As a temporary workaround until this is resolved, we can use a temp variable at the same level to bind and use as below

import ballerina/io;
import ballerina/xmldata;
import ballerina/http;

type Order record {
    string id;
    Product[] items;
};

type Product record {|
    string id;
    string name;
    Price price;
    int quantity;
|};

type Price record {|
    decimal amount;
    string currency;
|};

service / on new http:Listener(9090) {

    resource function post greeting() returns http:Ok|http:InternalServerError|error {
        xml payload = check io:fileReadXml("sample.xml");

        xml items = payload/*;
        // json converted = items.toJson();

        Order[] orders = from xml item in items
            let xml tempItem = item, Order o = check xmldata:fromXml(tempItem, Order)
            select o;
        io:println(orders);

        return <http:Ok>{};
    }
}

pcnfernando avatar Aug 17 '22 13:08 pcnfernando

@IMS94 shall we rename the issue may be as

XML langlib invocation within a query expression crashes during code generation

pcnfernando avatar Aug 17 '22 13:08 pcnfernando

@pcnfernando I see. Thanks for the information. Updated!

IMS94 avatar Aug 17 '22 14:08 IMS94

@IMS94 shall we rename the issue may be as

XML langlib invocation within a query expression crashes during code generation

This is not even xml langlib, right? It's the ballerina/xmldata module.

Actually, even the following without xmldata crashes.

type Order record {
    string id;
};

public function main() returns error? {
    xml items = xml ``;

    _ = from xml item in items
        let Order o = check fn(item)
        select o;
}

function fn(xml x) returns Order|error => error("err!");

MaryamZi avatar Aug 18 '22 03:08 MaryamZi

Seems to be crashing for all invocations passing xml type.

Workaround still valid

type Order record {
    string id;
};

public function main() returns error? {
    xml items = xml ``;

    _ = from xml item in items
        let xml temp = item, Order o = check fn(temp)
        select o;
}

function fn(xml x) returns Order|error => error("err!");

pcnfernando avatar Aug 18 '22 03:08 pcnfernando