How to? Collections without property names

40 views
Skip to first unread message

Guyllaume Cardinal

unread,
Jun 16, 2020, 4:11:43 PM6/16/20
to SnakeYAML
I'm trying to parse a YAML file with the following structure with SnakeYAML. However, I'm having issues since the documentation implies I need to have properties for each element of a collection.

application:
  variables
:
    API_KEY
: /secrets/gsaccount/gsaccount
    DB_GCP_PROJECT
:
        abc
-foo: [dev, uat]
        abc
-bar: [staging, prod]

In essence, when parsing application.variables, I'd like SnakeYAML to consider anything found in this property as Map<String, EnvironmentVariable>. With EnvironmentVariable implemented as such (or maybe this implementation wouldn't work).

public class EnvironmentVariable {
  private String value;
  private Map<String, List<String>> possibleValues;

  public EnvironmentVariable(String value) {
    this.value = value;
  }

  public EnvironmentVariable(Map<String, List<String>> value) {
    this.possibleValues = value;
  }

  public String getValue() {
    // Will handle logic to decide what to return here
  }
}

My Application model looks like this:

public class Application {
  private Map<String, EnvironmentVariable> variables;

  public Map<String, EnvironmentVariable> getVariables() {
    return variables;
  }

  public void setVariables(Map<String, EnvironmentVariable> environmentVariables) {
    this.variables = environmentVariables;
  }
}

Right now, SnakeYAML will fail when loading the given YAML with the following error:

java.lang.InstantiationException: NoSuchMethodException:org.cogeco.models.manifest.EnvironmentVariable.<init>()
 in 'reader', line 7, column 5:
        SIMPLE: foo
        ^


Any help would be greatly appreciated.

Guyllaume Cardinal

unread,
Jun 16, 2020, 4:14:12 PM6/16/20
to SnakeYAML

On Tuesday, June 16, 2020 at 4:11:43 PM UTC-4, Guyllaume Cardinal wrote:
...


Right now, SnakeYAML will fail when loading the given YAML with the following error:

java.lang.InstantiationException: NoSuchMethodException:org.cogeco.models.manifest.EnvironmentVariable.<init>()
 in 'reader', line 7, column 5:
        SIMPLE: foo
        ^


Can't edit my post and I made a mistake, the error would be:

java.lang.InstantiationException: NoSuchMethodException:org.cogeco.models.manifest.EnvironmentVariable.<init>()
in 'reader', line 7, column 5:
       API_KEY: /secrets/gsaccount/gsaccount
       ^


Uday Bhaskar Sarma Seetamraju

unread,
Jun 16, 2020, 5:22:16 PM6/16/20
to snakeya...@googlegroups.com
I suspect, it’s looking for the DEFAULT Constructor (of EnvironmentVariable).
If you can get past the error, then let’s see if you might also need a “setter” (in addition to the getter/getValue()).


--
You received this message because you are subscribed to the Google Groups "SnakeYAML" group.
To unsubscribe from this group and stop receiving emails from it, send an email to snakeyaml-cor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/snakeyaml-core/cdf84b37-cb30-4e4b-be0c-45323e871c80o%40googlegroups.com.

Joachim Durchholz

unread,
Jun 17, 2020, 1:44:52 AM6/17/20
to snakeya...@googlegroups.com
The

Am 16.06.20 um 22:11 schrieb Guyllaume Cardinal:
> |
> public class EnvironmentVariable {
> ...
>   public EnvironmentVariable(String value) {
>     this.value = value;
>   }
>
>   public EnvironmentVariable(Map<String, List<String>> value) {
>     this.possibleValues = value;
>   }
> ...
> }
> |
>
> Right now, SnakeYAML will fail when loading the given YAML with the
> following error:
>
> |
> java.lang.InstantiationException:
> NoSuchMethodException:org.cogeco.models.manifest.EnvironmentVariable.<init>()
>  in 'reader', line 7, column 5:
>         SIMPLE: foo
>         ^
> |

The reference to line 7, column 5 is a red herring, the information is
that calling EnvironmentVariable.<init> (constructor) with zero arguments.
EnvironmentVariable does not have a zero-arguments constructor, so the
instantiation (object construction) fails.

In theory the InstantiationException could be thrown by something else
(we'd need the stack trace to decide that), but the lack of a default
constructor is definitely a problem you'll need to fix if you want to
make SnakeYaml construct an EnvironmentVariable.

Regards,
Jo

Guyllaume Cardinal

unread,
Jun 18, 2020, 8:56:26 AM6/18/20
to SnakeYAML
I did indeed require a default constructor (coming from PHP and being thrown into Java by my employer, I didn't know default constructors weren't implied). However, I'm now getting an other error, one that I had seen before and that I don't know how to resolve:

Cannot create property=application for JavaBean=org.cogeco.models.manifest.Manifest@77c2494c
 in 'reader', line 1, column 1:
    version: 1
    ^
Cannot create property=environment_variables for JavaBean=org.cogeco.models.manifest.Application@477b4cdf
 in 'reader', line 4, column 3:
      name: Foobar
      ^
Cannot create property=abc-foo for JavaBean=org.cogeco.models.manifest.EnvironmentVariable@3eb25e1a
 in 'reader', line 9, column 7:
          abc-foo: [dev, uat]
          ^
Unable to find property 'abc-foo' on class: org.cogeco.models.manifest.EnvironmentVariable
 in 'reader', line 9, column 16:
          abc-foo: [dev, uat]
                   ^

 in 'reader', line 7, column 5:
        API_KEY: /secrets/gsaccount/gsac ... 
        ^

 in 'reader', line 4, column 3:
      name: Foobar
      ^

If I'm understanding this properly, SnakeYAML tries to call a setter for abc-foo, rather than just passing abc-foo: [dev, uat] as a Map<String, List<String>> to EnvironmentVariable. I'm not sure how I could tell SnakeYAML to just pass all of variables as a Map<String, EnvironmentVariable> rather than dig down on those properties.

Uday Bhaskar Sarma Seetamraju

unread,
Jun 18, 2020, 2:48:03 PM6/18/20
to snakeya...@googlegroups.com
I hope this is not turning into a Java Class :-)
Nothing to do with SnakeYAML.
I love Baeldung's website.
Try their code.  It just works!


--
You received this message because you are subscribed to the Google Groups "SnakeYAML" group.
To unsubscribe from this group and stop receiving emails from it, send an email to snakeyaml-cor...@googlegroups.com.

Guyllaume Cardinal

unread,
Jun 18, 2020, 3:24:52 PM6/18/20
to SnakeYAML
I stumbled on this article, but it's of no help. The examples are too simplistic. The only collection showcased has known properties, with a known value type. This is not the case in the YAML I put in my first post.

application:
  variables:
    API_KEY: /secrets/gsaccount/gsaccount
    DB_GCP_PROJECT:
        abc-foo: [dev, uat]
        abc-bar: [staging, prod]

Notice how the variables property cannot know its properties (which the examples on Baeldung examples assume), at best I can define it as a Map, but then the values of this Map are also variable, either a String or a LinkedHashMap<String, List<String>> and this is where SnakeYAML chokes. It will keep drilling down and try to find a setAbcFoo() property (as evidenced by the stack trace above).

If it is not a SnakeYAML issue, then I assume it's the model I defined. Then my question becomes, how would you define a model to represent the YAML so SnakeYAML parses it properly?


On Thursday, June 18, 2020 at 2:48:03 PM UTC-4, Uday Bhaskar Sarma Seetamraju wrote:
I hope this is not turning into a Java Class :-)
Nothing to do with SnakeYAML.
I love Baeldung's website.
Try their code.  It just works!


To unsubscribe from this group and stop receiving emails from it, send an email to snakeya...@googlegroups.com.

Uday Bhaskar Sarma Seetamraju

unread,
Jun 18, 2020, 4:17:46 PM6/18/20
to snakeya...@googlegroups.com
In java .. "Map<String, Object>" is NOT the same as "Map<String, List<String>>" or "Map<String, EnvironmentVariable>".
So, recommend you replace the latter 2 Map<> definitions .. with the 1st one.
People coming from Python/JS world are in for a shock with the precision required in Java-code.
At a minimum, get rid of your "EnvironmentVariable" class completely ,and use "Object" instead.
Map<String,Object> is recursive!

Now we're back to SnakeYAML topics.
Either your YAML contains "!classname" tags .. or, if that is Not feasible.. then, you write your own de-serialization/parsing/compose.. (https://yaml.org/spec/1.2/spec.html#id2762107)

YAML standard (and good/reference implementations) is going in the direction of not being bloated, and in becoming compact.
So, you are NOT going to ANY intelligence from the "basic" parser/composer (as in.. no intelligence like:- see if Guyllaume's class has a Map<String,Object> .. if not, is there a Map<String,<T>> and so on.. so on..)

Lastly, as you are coming from a PHP world, you will do just fine with Map<String,Object> without having the level of brittleness/sophistication that your EnvironmentVariable & Application JAVA-classes.

To unsubscribe from this group and stop receiving emails from it, send an email to snakeyaml-cor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/snakeyaml-core/e69aac85-c9c9-463f-9f47-71e84c97e69bo%40googlegroups.com.

Joachim Durchholz

unread,
Jun 20, 2020, 6:40:01 AM6/20/20
to snakeya...@googlegroups.com
Am 18.06.20 um 14:56 schrieb Guyllaume Cardinal:
> I did indeed require a default constructor (coming from PHP and being
> thrown into Java by my employer, I didn't know default constructors
> weren't implied).

They are implied if there is no constructor declaration.
Declare a nondefault constructor and the implied default constructor
goes away (but you can define it manually).
It's one of those small irregularities that you just have to know.

(Guyllaume has answered your actual questions it seems, so I am not
responsing to these.)

Guyllaume Cardinal

unread,
Jun 25, 2020, 11:53:54 AM6/25/20
to SnakeYAML
In java .. "Map<String, Object>" is NOT the same as "Map<String, List<String>>" or "Map<String, EnvironmentVariable>".
So, recommend you replace the latter 2 Map<> definitions .. with the 1st one.

Wow, that just worked instantly. Now I just feel silly...

People coming from Python/JS world are in for a shock with the precision required in Java-code

No kidding... This is supposed to be a temporary assignment, but if my employer keeps me in this role, I'll have to request a formation or something. Java is a beast of its own.

Thanks a lot, I was really off on the solution and I'm not sure I would have succeeded without your help.
Reply all
Reply to author
Forward
0 new messages