Tag: Java8

  • How to ignore Maven build erros due to JavaDoc with Java 8

    Java 8 is a bit more strict in JavaDoc parsing. This can lead to build failures in Maven when building the repo with warnings like:

    Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.7:jar (attach-javadocs) on project [projectname]: MavenReportException: Error while creating archive:
    Exit code: 1 - [path-to-file]:[linenumber]: warning: no description for @param

    Sure, the good solution would be to fix the JavaDocs. But in cases where you just clone a foreign repo, you probably just want to get it run and not start fixing it.

    To ignore the erros, just turn off doclint by adding the following <configuration> tag to your pom.xml:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>2.10.2</version>
        <executions>
            <execution>
                <id>attach-javadocs</id>
                <goals>
                    <goal>jar</goal>
                </goals>
                <configuration> <!-- add this to disable checking -->
                    <additionalparam>-Xdoclint:none</additionalparam>
                </configuration>
            </execution>
        </executions>
    </plugin>
    

    Some more solutions can be found in this StackOverflow thread.

  • How to get List of Objects from deeper level in Json via GSON

    Sometimes you get a quite nested Json response but the only thing you need is a list of classes in a certain branch of the Json document (like a response of Yahoo’s YQL query).

    Assume just the following json document:

    {
    "fieldA": {
        "fieldB": {
            "fields": [
                { "foo": "test1", "bar": "test2"},
                { "foo": "test11", "bar": "test22"}
             ]
          }
       }
    }
    

    And the only thing you need is the fields array.
    A Java8 way to get the fields as a list would be:

    List<FooBar> quotes2 = Stream.of(gson.fromJson(json, JsonObject.class)
    	.getAsJsonObject("foo")
    	.getAsJsonObject("bar")
    	.getAsJsonArray("foobar"))
    	.flatMap(e -> Stream.of(gson.fromJson(e, FooBar[].class)))
    	.collect(Collectors.toList());
    

    But that’s quite some code. Okay if you only need it once, but as soon as you need this several times it clearly violates the DRY principle. Gson (which I am using a lot) doesn’t seem to provide a simple way for doing this. Except creating the whole hierarchy as Java Classes, which might just be overkill.

    Solving the problem in a more generic way is the way to go – but it als requires creating generic arrays:

    class Gsons{
        public static <T> List<T> asList(String json, String path, Class<T> clazz) {
            Gson gson = new Gson();
            String[] paths = path.split("\\.");
            JsonObject o = gson.fromJson(json, JsonObject.class);
            for (int i = 0; i < paths.length - 1; i++) {
                o = o.getAsJsonObject(paths[i]);
            }
            JsonArray jsonArray = o.getAsJsonArray(paths[paths.length - 1]);
            Class<T[]> clazzArray = (Class<T[]>) ((T[]) Array.newInstance(clazz, 0)).getClass();
            T[] objectArray = gson.fromJson(jsonArray, clazzArray);
            return Arrays.asList(objectArray);
        }
    }
    

    The only things to do are creating a class for the entities and calling the method:

    List<FooBar> fooBars = Gsons.asList(json, "fieldA.fieldB.fields", FooBar.class);
    
  • Java 8 Streams: Collecting items into a Map of (Key, Item)

    Once in a while I come across the task where I have a list of Items that I want to filter and afterwards store in a map. Usually the key is a property of the Item: anItem.name -> anItem

    In the usual Java way this looked like the following:

    Map<String, Stuff> map = new HashMap<>();
    for (Stuff s : list) {
        if (!s.name.equals("a")){
            map.put(s.name, s);
        }
    }
    

    Nothing really special, but it somehow doesn’t look too nice. Yesterday I thought: in Scala I would emit tuples and call .toMap. Isn’t that also possible with Java 8 Streams? And indeed it is:

    Map<String, Item> map = l.stream()
        .filter(s -> !s.name.equals("a"))
        .collect(toMap(s -> s.name, s -> s)); // toMap is a static import of Collectors.toMap(...)
    

    This looks compact and readable!

    If you don’t like s -> s, just use identity() function of the Function class. Actually I do not like static imports very much as as they make the code less readable, but in this case I would decide for static imports.

    Map<String, Item> map = l.stream()
        .filter(s -> !s.name.equals("a"))
        .collect(toMap(s -> s.name, identity())); // toMap and identity are imported statically