eclipse-vertx / vertx-codegen

Vert.x code generator for asynchronous polyglot APIs
Apache License 2.0
105 stars 92 forks source link

Code generation does not with with modules and JDK 16 #327

Closed jeremy-florte closed 3 years ago

jeremy-florte commented 3 years ago

Version

4.0.3

Context

It is an update of a previous issue that raised when using modules and code generator with a JDK 11. Testing with JDK 16 raised another issue because now, instead of throwing NPE, java implementation returns null.

This stands in CodeGen class.

Previous update was (line 71):


Predicate<Element> implFilter = elt -> {
  PackageElement pkg;
  try {
    pkg = elementUtils.getPackageOf(elt);
  } catch (NullPointerException e) {
  // This might happen with JDK 11 using modules and it looks like a JDK bug
  return true;
  }

  String fqn = pkg.getQualifiedName().toString();
  return !fqn.contains(".impl.") && !fqn.endsWith(".impl");
};

Steps to reproduce

service-proxy-howto.zip

  1. uncompress the provided archive
  2. run command mvn compile exec:java
  3. you should get an error about a null pointer exception:
 Fatal error compiling: java.lang.NullPointerException: Cannot invoke "javax.lang.model.element.PackageElement.getQualifiedName()" because "pkg" is null

Proposed fix

The issue stands in CodeGen class. Following fix resolves the issue (tested with latest 4.1.0-SNAPSHOT version):

Predicate<Element> implFilter = elt -> {
  PackageElement pkg;
  try {
    pkg = elementUtils.getPackageOf(elt);
  } catch (NullPointerException e) {
  // This might happen with JDK 11 using modules and it looks like a JDK bug
  return true;
  }

  if (null == pkg) {
    return true;
  } else {
    String fqn = pkg.getQualifiedName().toString();
    return !fqn.contains(".impl.") && !fqn.endsWith(".impl");
  }
};

A kind of shorter syntax could be:

Predicate<Element> implFilter = elt -> {
  try {
    // Since JDK 16, method elementUtils.getPackageOf(Element) can return null instead of throwing a NPE.
    return Optional.ofNullable(elementUtils.getPackageOf(elt))
                   .map(pkg -> pkg.getQualifiedName().toString())
                   .map(fqn -> !fqn.contains(".impl.") && !fqn.endsWith(".impl"))
                   .orElse(true);
  } catch (NullPointerException e) {
    // This might happen with JDK 11 using modules and it looks like a JDK bug
    return true;
  }
};

NB: does not compile with a JDK 16 (compiles fine with JDK 11) but executes well with JDK 11 and 16.

Extra

OS version: pop OS (kind of Ubuntu 20.04) Java: 16 open JDK

vietj commented 3 years ago

@jeremy-florte can you provide a PR ?

jeremy-florte commented 3 years ago

Sure, I'm off today but I'll do it asap.

jeremy-florte commented 3 years ago

@vietj Could you give me write access to the repo ? My branch is ready but I cannot push.

vietj commented 3 years ago

you need to provide a pull request

jeremy-florte commented 3 years ago

@vietj P.R here: https://github.com/vert-x3/vertx-codegen/pull/328

vietj commented 3 years ago

thanks!