Java Parser Error: Builder not found for <NodeTuple keyNode=<org.yaml.snakeyaml.nodes.ScalarNode


#1

I am having difficulties running the Java Parser.

Here is my simple Java useage:

Raml baseRaml = new RamlDocumentBuilder().build("/backup/base.raml");

And here is the error I receive:

Exception in thread "main" java.lang.RuntimeException: Builder not found for <NodeTuple keyNode=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=resource)>; valueNode=<org.yaml.snakeyaml.nodes.MappingNode (tag=tag:yaml.org,2002:map, values={ key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=displayName)>; value=<NodeTuple keyNode=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=displayName)>; valueNode=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=First One)>> }{ key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=is)>; value=1468177767 }{ key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=options)>; value=434091818 }{ key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=connect)>; value=2114889273 }{ key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=trace)>; value=1504109395 }{ key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=patch)>; value=1908316405 }{ key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=delete)>; value=25126016 }{ key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=put)>; value=672320506 }{ key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=get)>; value=1349414238 }{ key=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=/{resourceId})>; value=1740000325 })>>
    at org.raml.parser.builder.DefaultTupleBuilder.getBuilderForTuple(DefaultTupleBuilder.java:68)
    at org.raml.parser.visitor.YamlDocumentBuilder.onTupleStart(YamlDocumentBuilder.java:272)
    at org.raml.parser.visitor.NodeVisitor.doVisitMappingNode(NodeVisitor.java:145)
    at org.raml.parser.visitor.NodeVisitor.visitDocument(NodeVisitor.java:209)
    at org.raml.parser.visitor.YamlDocumentBuilder.build(YamlDocumentBuilder.java:90)
    at org.raml.parser.visitor.YamlDocumentBuilder.build(YamlDocumentBuilder.java:102)
    at org.raml.parser.visitor.YamlDocumentBuilder.build(YamlDocumentBuilder.java:78)
    at my.group.App.main(App.java:24)

I notice that if I remove any lines beginning with / (whack), the file does not error out. I am using the simple RAML example from Gtihub to test. Content are here:

#%RAML 0.8
---
title: Example API
baseUri: http://example.com
securitySchemes:
  - basic:
      type: Basic Authentication
traits:
  - secured:
      description: Some requests require authentication
  - unsecured:
      description: This is not secured
  - catpictures:
      description: requires cat headers
  - anotherTrait: {}
  - andAnotherTrait: {}
  - andYetAnotherTrait: {}
  - aFinalTrait: {}
  - someParameterizedTrait:
      description: <<someParameterName>>
resourceTypes:
  - longCollectionName:
      description: |
        This is a description. It can be long.
        # Headers
        It can have headers, and _italic_, and **bold** text.
        # Length
        Because it is arbitrary markdown, it can be arbitrarily long.
documentation:
  - title: Getting Started
    content: |
      # Header
      Content
      ## Subheader
      **Bolded content**
resource:
  displayName: First One
  is: [secured]
  options:
    responses:
      200:
  connect:
    responses:
      200:
  trace:
    responses:
      200:
  patch:
    responses:
      200:
  delete:
    responses:
      200:
      201:
      203:
  put:
    responses:
      200:
      201:
      203:
  get:
    description: get the first one
    headers:
      x-custom:
    responses:
      200:
  /{resourceId}:
    description: This is a resource description *with* some _markdown_ embedded in it
    uriParameters:
      resourceId:
        required: true
        description: Which resoure would you like to view
    get:
      description: |
        Instagram’s API uses the [OAuth 2.0 protocol](http://tools.ietf.org/html/draft-ietf-oauth-v2-12) for simple, but effective authentication and authorization. OAuth 2.0 is much easier to use than previous schemes; developers can start using the Instagram API almost immediately. The one thing to keep in mind is that all requests to the API must be made over SSL (https:// not http://)
        ## Do you need to authenticate?
        For the most part, Instagram’s API only requires the use of a _client_id). A client_id simply associates your server, script, or program with a specific application. However, some requests require authentication - specifically requests made on behalf of a user. Authenticated requests require an _access_token_. These tokens are unique to a user and should be stored securely. Access tokens may expire at any time in the future.
        Note that in many situations, you may not need to authenticate users at all. For instance, you may request popular photos without authenticating (i.e. you do not need to provide an access_token; just use your client ID with your request). We only require authentication in cases where your application is making requests on behalf of a user (commenting, liking, browsing a user’s feed, etc.).
        ## Receiving an access_token
      queryParameters:
        filter:
          description: What to filter
          type: string
      responses:
        200:
    post:
      body:
        application/json:
        application/x-www-form-urlencoded:
          formParameters:
            name:
              description: The name of the resource to create
              type: string
              example: Comment
            description:
              description: A description of the resource to create
              type: string
              example: User-generated content pertinent to the associated blog post
        multipart/form-data:
          formParameters:
            name:
              description: The name of the resource to create
              type: string
              example: Comment
            description:
              description: A description of the resource to create
              type: string
              example: User-generated content pertinent to the associated blog post
      responses:
        200:
        201:
        203:

/another/resource:
  displayName: Cats
  type: longCollectionName
  is: [secured, catpictures, anotherTrait, andAnotherTrait]
  connect: !!null
  head:
    responses:
      200:
      201:
      203:
  get:
    queryParameters:
      chunk:
        displayName: page
        description: Which page to display
        type: integer
        example: 1
        minimum: 1
        maximum: 100
        required: true
      order:
        description: The sort order of resources
        type: string
        enum: ["oldest", "newest"]
        example: oldest
        minLength: 5
        maxLength: 7
        default: newest
      query:
        description: A query parameter
        repeat: true

/resource-with-headers:
  displayName: Resource With headers
  get:
    headers:
      x-custom-header:
        displayName: Custom header
        description: This header is used to send data that...
        type: string
        pattern: ^\w+$
      x-p-{*}:
        displayName: Parameterized header

/secured-resource:
  displayName: SO SECURE
  get:
    securedBy: [basic]
/resource-with-method-level-traits:
  displayName: First One
  is: [secured]
  get:
    is: [unsecured, catpictures, anotherTrait, andAnotherTrait, andYetAnotherTrait, aFinalTrait, {someParameterizedTrait: { someParameterName: someParameterValue }}]
    description: get the first one
/resource-with-form-and-multipart-form-parameters:
  get:
    queryParameters:
      some_query_param:
            displayName: Some Query Param
            description: Your value for some thing.
            type: string
            required: true
            example: "my value"
    body:
      application/json:
        example: |
            {
              "api_key": "c4f820f0420a013ea143230c290fbf99",
              ...
            }
      application/x-www-form-urlencoded:
        formParameters:
          api_key:
            displayName: API Key
            description: Your license key for the application. Please contact developer@nzpost.co.nz for a license key
            type: string
            required: true
            example: "c4f820f0420a013ea143230c290fbf99"
      multipart/form-data:
        formParameters:
          api_key:
            displayName: API Key
            description: Your license key for the application. Please contact developer@nzpost.co.nz for a license key
            type: string
            required: true
            example: "c4f820f0420a013ea143230c290fbf99"
/resource-with-repeatable-params:
  post:
    queryParameters:
      someParam:
        repeat: true
      notRepeatable:
    body:
      application/x-www-form-urlencoded:
        formParameters:
          someFormParam:
            repeat: true
      multipart/form-data:
        formParameters:
          someMultipartFormParam:
            type: file
            repeat: true
          someMultipartFormParamWithMultipleTypes:
            - type: file
            - type: string
              repeat: true
    headers:
      someHeader:
        repeat: true
      x-meta-{*}:
        repeat: true

Again, if I remove everything beginning with /, the file is processed without error.


#2

BTW, I am using RAML parser 0.8.12:

org.raml raml-parser 0.8.12

#3

Hi @mtyson, can you raise the same issue on https://github.com/raml-org/raml-java-parser/issues. That makes it easier for the responsible developers to see and track your issue.


#4

BTW, can you try to copy & paste the following - I made some adjustments:

#%RAML 0.8
---
title: Example API
baseUri: http://example.com
securitySchemes:
  - basic:
      type: Basic Authentication
traits:
  - secured:
      description: Some requests require authentication
  - unsecured:
      description: This is not secured
  - catpictures:
      description: requires cat headers
  - anotherTrait: {}
  - andAnotherTrait: {}
  - andYetAnotherTrait: {}
  - aFinalTrait: {}
  - someParameterizedTrait:
      description: <<someParameterName>>
resourceTypes:
  - longCollectionName:
      description: |
        This is a description. It can be long.
        # Headers
        It can have headers, and _italic_, and **bold** text.
        # Length
        Because it is arbitrary markdown, it can be arbitrarily long.
documentation:
  - title: Getting Started
    content: |
      # Header
      Content
      ## Subheader
      **Bolded content**
/resource:
  displayName: First One
  is: [secured]
  options:
    responses:
      200:
  connect:
    responses:
      200:
  trace:
    responses:
      200:
  patch:
    responses:
      200:
  delete:
    responses:
      200:
      201:
      203:
  put:
    responses:
      200:
      201:
      203:
  get:
    description: get the first one
    headers:
      x-custom:
    responses:
      200:
  /{resourceId}:
    description: This is a resource description *with* some _markdown_ embedded in it
    uriParameters:
      resourceId:
        required: true
        description: Which resoure would you like to view
    get:
      description: |
        Instagram’s API uses the [OAuth 2.0 protocol](http://tools.ietf.org/html/draft-ietf-oauth-v2-12) for simple, but effective authentication and authorization. OAuth 2.0 is much easier to use than previous schemes; developers can start using the Instagram API almost immediately. The one thing to keep in mind is that all requests to the API must be made over SSL (https:// not http://)
        ## Do you need to authenticate?
        For the most part, Instagram’s API only requires the use of a _client_id). A client_id simply associates your server, script, or program with a specific application. However, some requests require authentication - specifically requests made on behalf of a user. Authenticated requests require an _access_token_. These tokens are unique to a user and should be stored securely. Access tokens may expire at any time in the future.
        Note that in many situations, you may not need to authenticate users at all. For instance, you may request popular photos without authenticating (i.e. you do not need to provide an access_token; just use your client ID with your request). We only require authentication in cases where your application is making requests on behalf of a user (commenting, liking, browsing a user’s feed, etc.).
        ## Receiving an access_token
      queryParameters:
        filter:
          description: What to filter
          type: string
      responses:
        200:
    post:
      body:
        application/json:
        application/x-www-form-urlencoded:
          formParameters:
            name:
              description: The name of the resource to create
              type: string
              example: Comment
            description:
              description: A description of the resource to create
              type: string
              example: User-generated content pertinent to the associated blog post
        multipart/form-data:
          formParameters:
            name:
              description: The name of the resource to create
              type: string
              example: Comment
            description:
              description: A description of the resource to create
              type: string
              example: User-generated content pertinent to the associated blog post
      responses:
        200:
        201:
        203:

/another/resource:
  displayName: Cats
  type: longCollectionName
  is: [secured, catpictures, anotherTrait, andAnotherTrait]
  connect: !!null
  head:
    responses:
      200:
      201:
      203:
  get:
    queryParameters:
      chunk:
        displayName: page
        description: Which page to display
        type: integer
        example: 1
        minimum: 1
        maximum: 100
        required: true
      order:
        description: The sort order of resources
        type: string
        enum: ["oldest", "newest"]
        example: oldest
        minLength: 5
        maxLength: 7
        default: newest
      query:
        description: A query parameter
        repeat: true

/resource-with-headers:
  displayName: Resource With headers
  get:
    headers:
      x-custom-header:
        displayName: Custom header
        description: This header is used to send data that...
        type: string
        pattern: ^\w+$
      x-p-{*}:
        displayName: Parameterized header

/secured-resource:
  displayName: SO SECURE
  get:
    securedBy: [basic]
/resource-with-method-level-traits:
  displayName: First One
  is: [secured]
  get:
    is: [unsecured, catpictures, anotherTrait, andAnotherTrait, andYetAnotherTrait, aFinalTrait, {someParameterizedTrait: { someParameterName: someParameterValue }}]
    description: get the first one
/resource-with-form-and-multipart-form-parameters:
  get:
    queryParameters:
      some_query_param:
            displayName: Some Query Param
            description: Your value for some thing.
            type: string
            required: true
            example: "my value"
    body:
      application/json:
        example: |
            {
              "api_key": "c4f820f0420a013ea143230c290fbf99"
            }
      application/x-www-form-urlencoded:
        formParameters:
          api_key:
            displayName: API Key
            description: Your license key for the application. Please contact developer@nzpost.co.nz for a license key
            type: string
            required: true
            example: "c4f820f0420a013ea143230c290fbf99"
      multipart/form-data:
        formParameters:
          api_key:
            displayName: API Key
            description: Your license key for the application. Please contact developer@nzpost.co.nz for a license key
            type: string
            required: true
            example: "c4f820f0420a013ea143230c290fbf99"
/resource-with-repeatable-params:
  post:
    queryParameters:
      someParam:
        repeat: true
      notRepeatable:
    body:
      application/x-www-form-urlencoded:
        formParameters:
          someFormParam:
            repeat: true
      multipart/form-data:
        formParameters:
          someMultipartFormParam:
            type: file
            repeat: true
          someMultipartFormParamWithMultipleTypes:
            - type: file
            - type: string
              repeat: true
    headers:
      someHeader:
        repeat: true
      x-meta-{*}:
        repeat: true

#5

Thanks christian - I did open the issue on github: https://github.com/raml-org/raml-java-parser/issues/94

I tried with your updated file but got the same results.


#6

Thanks - guess the developer will hopefully reach out to you. :slightly_smiling: