Git Product home page Git Product logo

eclipse-null-eea-augments's Introduction

Build Status

Eclipse External null Annotations (EEA)

This repository contains *.eea files and example projects how to use this.

If you like/use this project, a Star / Watch / Follow on GitHub is appreciated.

How to use this

See theses slides here from this EclipseCon Europe 2016 presentation for some background about this project.

To automatically Enable Annotation-based Null Analysis in the Eclipse Project Preferences correctly (e.g. when you import the examples/ here), we highly recommend you install the eclipse-external-annotations-m2e-plugin Maven IDE (M2E) Configurator Eclipse plugin. (On Eclipse m2e versions < 1.8 (shipped with Oxygen), you also had to install m2e-jdt-compiler, but with M2E 1.8 in Oxygen that is not necessary anymore, even harmful; see below.)

Contribute

This project aims to develop an active community of contributors, and not remain controlled by a single person. Anyone making 3 intelligent contributions to this repo may ask to be promoted from a contributor to a committer with full write access by opening an issue requesting it. (We reserve the right to re-remove committers in exceptional circumstances, and after long periods of inactivity.)

We intend to liberally and quickly merge any contributions with additions to EEA, and avoid delays due to lengthy reviews (which are anyway kind of difficult to do rapidly and at scale until we solve issue #16), based on the idea that having an EEA that can be tested is better than none.

We intend to spend more time and request community feedback from engaged previous contributors on any proposed changes to existing EEA in this repo. When making contributions with changes, please explain what is wrong in the current version in the commit message.

We generally do not "self merge", but let other committers merge our own changes.

We hang out and chat about this project on https://mattermost.eclipse.org/eclipse/channels/jdt-null-analysis

Troubleshooting

  • Uninstall the jbosstools/m2e-jdt-compiler to fix this problem: Conflicting lifecycle mapping (plugin execution "org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (execution: default-compile, phase: compile)"). To enable full functionality, remove the conflicting mapping and run Maven->Update Project Configuration.

  • Do mvn install of the examples/maven/jdt-ecj-settings to fix this problem, due to M2E Bug 522393: CoreException: Could not get the value for parameter compilerId for plugin execution default-testCompile: PluginResolutionException: Plugin org.apache.maven.plugins:maven-compiler-plugin:3.5.1 or one of its dependencies could not be resolved: Failure to find ch.vorburger.nulls.examples:jdt-ecj-settings:jar:1.0.0-SNAPSHOT

Future

If this is found to be of general interest, perhaps this could move to eclipse.org. If this happens, it would be imperative to keep it very easy for anyone to contribute via Pull Requests on GitHub (and not, or not you only, eclipse.org Gerrit changes).

eclipse-null-eea-augments's People

Contributors

bananeweizen avatar ctron avatar dependabot[bot] avatar focbenz avatar j-n-k avatar jason-faust avatar kwin avatar lpmi-13 avatar maggu2810 avatar rpraml avatar sebthom avatar sylvainlaurent avatar tomvandenberge avatar triller-telekom avatar vorburger avatar wborn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eclipse-null-eea-augments's Issues

Move this repository to eclipse.org

When I had more time for this project than I have now, there was a private email thread which investigated if it would be possible to move this repository from here to eclipse.org. The outcome was that it was feasible and eclipse.org would be open to it.

I never followed-up on that - would anyone else be interested to take over getting this done? I could find the old email thread and forward it to anyone interested in taking this on. ou probably need to already be set up on eclipse.org though.

@maggu2810 @kwin @ctron @brychcy @sylvainlaurent

Map computeIfAbsent is incorrect

@J-N-K I know you sort of mentioned this in #116 but I'm now fairly positive computeIfAbsent for map is wrong.

computeIfAbsent
 (TK;Ljava/util/function/Function<-TK;+TV;>;)TV;
 (TK;L1java/util/function/Function<-TK;+T0V;>;)T0V;

Should be

computeIfAbsent
 (TK;Ljava/util/function/Function<-TK;+TV;>;)TV;
 (TK;L1java/util/function/Function<-TK;+TV;>;)TV;

V is a free variable. It is not @Nullable like on get.

The Javadoc is:

     * @return the current (existing or computed) value associated with
     *         the specified key, or null if the computed value is null

For a Map<@NonNull String, @NonNull String> I think a reasonable assumption is the mappingFunction should return what type the map's key is and thanks to the generic V being @NonNull String Eclipse will enforce it. I'm not sure why you had problems with this but if Map is correctly annotated I get correct warnings like:

Map<@NonNull String, @NonNull String> m; ...
m.computeIfAbsent(key, k -> null /* warning here */);

Ditto for computeIfPresent EDIT I got confused with some other method on ConcurrentHashMap like removeIf.

These annotations are on ConcurrentHashMap as well.

Add unit test which parses the files to make sure they are valid

Please add a unit test that tries to read all *.eea files and makes sure the syntax is valid.

Background: In my Eclipse (since 2020-06 or 4.16), the annotate menu is broken and doesn't allow me to create annotations anymore (nothing happens when I select the item and the child menus which were there before are missing).

So I need a way to validate the hand-crafted annotations.

Single Maven artifact (JAR) with ALL EEAs

#29 (comment) has raised the idea of producing a single Maven artifact (JAR) with ALL of the EEAs from the different folders in this repo.

I think what would be both quite easy to do and probably a useful extension in general for some people who prefer single instead of many small per library artifacts.

You could just introduce a new Maven POM artifact in this project, like say an org.lastnpe.eea:all-eea, which using some appropriate Maven plugin... either some fancy überjar thingie, or probably this can be done somehow with the maven-dependency-plugin ?

Actually making the latest build of that artifact available on a URL is out of scope of this issue, and is either #29 for non-SNAPSHOT or (revive) #14, if there is any interest.

PR for this would be welcome.. @triller-telekom perhaps you would like to contribute this? 😺

How to make EEA easier to review, diff & merge

While working on #10 and merging some EEA java.* from an existing project (tracecompass) with some EEA I had already created in this project before, I realized that diff & merge of *.eea is quite a PITA... e.g. Git is often wrong and would have lost things, because it's algorithm for finding dupes assume you want to change things when really you want to add.

As (or perhaps even more...) important than diff & merge is simple "review-ability" - unless you are really used to the EEA syntax (which e.g. I currently am not yet..), it's kind of really hard actually to immediately understand exactly what gets changed in e.g. something like the Map get() and remove() of PR #21.

The goal of this issue to collect community feedback is there's anything that can be done to help with this:

  • Git settings for *.eea ?!
  • Minor changes to the EEA file format (probably too late already)
  • Alternative friendlier syntax with generator/converter to EEA?

@svenefftinge once suggested the idea of an Xtext grammar for this... that could be cool, some day! ;-) Imagine representing EEA as a very Java-like Xbase validating DSL language, with the respective @nullable etc. annotations as if it was Java (but without any Method bodies), and then a little EEA generator off that - that could be neat. BUT one problem that deserves more thought before jumping into such a DSL (which isn't really THAT hard to put together...) is the workflow... The Eclipse IDE integration using which developers maintain EEA files directly (which is how EEA get created today) would become much MORE cumbersome - after you Quick Fix an EEA, how do you get the EEA changed? In ideal world, that would have to be some fancy bi-directional thingie - but that's a little less immediate easy like pie out of the box, e.g. with Xtext.

Discussion: Eclipse IDE Java projects + external annotations

I am opening this issue as a discussion on how one could implement support for projects of type "Java project" within the Eclipse IDE.

As briefly mentioned in #52 (comment) the plugin eclipse-external-annotations-m2e-plugin is only for "Maven projects" within the Eclipse IDE.

Since the Eclipse JDT compiler is able to read the external annotations via its special "-annotationpath CLASSPATH" if you run it on the console, I am wondering how the eclipse-external-annotations-m2e-plugin makes use of it.

The GUI of the Eclipse IDE itself does not allow inserting "CLASSPATH" as a value in the projects build path on where it can find the external annotations.

So I am wondering if anyone has an idea on how to tell the jdt compiler within the IDE to read its external annotations fro the CLASSPATH?

Improve documentation for Eclipse IDE and maven setup

The Maven usage documentation is a bit unclear to me:

In #29 (comment) @vorburger mentions that one can use the eeas as maven dependencies like this:

<dependencies>
<dependency>
      <groupId>org.lastnpe.eea</groupId>
      <artifactId>jdk-eea</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <scope>provided</scope>
    </dependency>

and then configure the jdt compiler like this

<compilerId>jdt</compilerId>
          <compilerArguments>
            <annotationpath>CLASSPATH</annotationpath>

But WHO sets this "CLASSPATH"? Is it set by maven and filled with everything from the "" section?

Regarding the use within Eclipse:

You are saying that https://github.com/lastnpe/eclipse-external-annotations-m2e-plugin can be used to setup my projects to use the jars inside a maven repo. But how?

Allows to configure Java Compiler Project Properties from maven-compiler-plugin; read either from a dependency of maven-compiler-plugin containing a org.eclipse.jdt.core.prefs file, or from configuration/compilerArguments/properties.

Here I understand that I can put a "org.eclipse.jdt.core.prefs" config file in my repository that has setting for eea. But how and when ware they applied to my projects within Eclipse?

Allows to configure the path to external annotations for the Maven Dependencies and JRE classpath containers. The path is either taken from the "m2e.jdt.annotationpath" property in POM files, if it exists (this for configuring one single archive of *.eea for ALL Maven dependencies AND the JRE),

From this I understand that I can set the "m2e.jdt.annotationpath" property in my pom.xml and whatever is in there will be copied into my project settings for all my projects in the workspace? When and how? Also what do I write into that property? "CLASSPATH"? like I do for the "annotationpath" in the jdt settings of the pom.xml?

Sorry about these questions, but I am still learning maven and that is why I am struggeling to understand the examples you are providing. Maybe this way the documentation can be improved...

[question] consideration to move under eclipse umbrella ?

Have we considered to move this project under eclipse project umbrella ? Having it under eclipse and available to be included as part of Eclipse update site will also make it easy to be discovered and could implement features to suggest this plugin installation as well.

Collectors toList/toSet/toCollection should have a return value of Nonnull

It appears the Collectors.eaa file is incorrect.

That is Collectors.toSet() and Collectors.toList() are reported as @Nullable.

Original toSet:

toSet
 <T:Ljava/lang/Object;>()Ljava/util/stream/Collector<TT;*Ljava/util/Set<TT;>;>;
 <T:Ljava/lang/Object;>()Ljava/util/stream/Collector<TT;*L1java/util/Set<TT;>;>;

Should be marked as L1

toSet
 <T:Ljava/lang/Object;>()Ljava/util/stream/Collector<TT;*Ljava/util/Set<TT;>;>;
 <T:Ljava/lang/Object;>()L1java/util/stream/Collector<TT;*L1java/util/Set<TT;>;>
                                        // ^^--- I guess this is the return value

I'm still learning the format of EEA so perhaps this is wrong but regardless my code inspection of toList/toSet to not be possible for it to return null.

Enable DCO signoff via web UI

Since you require DCO, please enable sign-off via web UI as explained herehttps://github.blog/changelog/2022-06-08-admins-can-require-sign-off-on-web-based-commits/#how-to-enable-required-signoffs-for-a-repository

Thanks!

Invite @jason-faust and @J-N-K as committers

@jason-faust and @J-N-K in #85 seem to show interest in this project - great!

Personally I'm currently not in a position to maintain this project. Other committers (@sylvainlaurent @kaikreuzer @maggu2810 @brychcy @ctron @rPraml #75 @victornoel) don't seem to be either anymore?

Ergo, and inspired by https://github.com/lastnpe/eclipse-null-eea-augments#contribute, the responsible open source stewardship thing for the last person to do in such situations is to invite both @jason-faust and @J-N-K as committers so that they can maintain this project!

I've just sent you invites via GitHub, which you can Accept, or Decline. You will require to have 2FA enabled. This issue can be used to discuss anything related to it. Please close it yourselves after you've concluded this.

Welcome - and best of luck with maintaining this project! 😈

Tests fail on Java 17

I try to use Java 17 for everything nowadays but unfortunately this project fails to build with it:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.lastnpe.eea.test.SelfTest
[FAIL] java/time/ZonedDateTime.eea: Unsupported class file major version 61
[FAIL] java/time/temporal/TemporalQuery.eea: Unsupported class file major version 61
[FAIL] java/time/LocalDate.eea: Unsupported class file major version 61
[FAIL] java/time/LocalTime.eea: Unsupported class file major version 61
[FAIL] java/lang/Thread.eea: Unsupported class file major version 61
[FAIL] java/lang/RuntimePermission.eea: Unsupported class file major version 61
[FAIL] java/lang/IllegalAccessError.eea: Unsupported class file major version 61
[FAIL] java/lang/Integer.eea: Unsupported class file major version 61
[FAIL] java/lang/NullPointerException.eea: Unsupported class file major version 61
[FAIL] java/lang/Runtime$Version.eea: Unsupported class file major version 61
[FAIL] java/lang/VirtualMachineError.eea: Unsupported class file major version 61
...
[FAIL] javax/swing/DefaultListCellRenderer.eea: Unsupported class file major version 61
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.139 sec <<< FAILURE! - in org.lastnpe.eea.test.SelfTest
org.lastnpe.eea.test.SelfTest.testEeaConsistency()  Time elapsed: 0.138 sec  <<< FAILURE!
org.opentest4j.AssertionFailedError: There were eea inconsistences detected
	at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:39)
	at org.junit.jupiter.api.Assertions.fail(Assertions.java:117)
	at org.lastnpe.eea.test.SelfTest.testEeaConsistency(SelfTest.java:30)


Results :

Failed tests: 
  org.lastnpe.eea.test.SelfTest#testEeaConsistency  There were eea inconsistence...

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0

It works better after upgrading the ASM dependency, but probably due to some internal Java changes the method signatures changed and the SelfTest still fails:

[INFO] Running org.lastnpe.eea.test.SelfTest
[FAIL] java/security/acl/Permission.eea: Class not found
[FAIL] java/util/HashMap.eea: Did not find: getNode (ILjava/lang/Object;)Ljava/util/HashMap$Node<TK;TV;>;
Candidates:
getNode
 (Ljava/lang/Object;)Ljava/util/HashMap$Node<TK;TV;>;
 (Ljava/lang/Object;)Ljava/util/HashMap$Node<TK;TV;>;
[FAIL] java/lang/ClassNotFoundException.eea: Did not find: getCause ()Ljava/lang/Throwable;
No Candidates found
[FAIL] java/util/jar/JarFile.eea: Did not find: getMetaInfEntryNames ()[Ljava/lang/String;
No Candidates found
[FAIL] java/util/jar/JarInputStream.eea: Did not find: getBytes (Ljava/io/InputStream;)[B
No Candidates found

Discussion: Do we really need to properly version EEA, and if so, how would you like to?

We haven't had the need to give much thought really re. properly version-ing EEA JARs... the way we currently have, it is just: Single version (in the Maven GAV sense) for all EEA as currently in this repo, perhaps even timestamp type versions discussed in the regular release issue, and not a per-library specific version.

I always thought that should be just fine, because I don't really see JDK, Guava, slf4j & Co. ever doing API incompatible changes which would require different EEA for different versions of those libraries - but maybe that's a bit overly optimistic, in the long run?

If someone disagree with this admitedly a bit simplistic view, then let's discuss here... or, always better than words to discuss, just start proposing PR with changes to make this stuff more version aware!

If someone is really motivated to pick this up, I guess we could start adding something OSGi like version ranges into the eea-for-gav files after the G:A? And then have our eclipse-external-annotations-m2e-plugin be a bit smarter than it is today, and read such versions, and iff present (backwards compatible) find the EEA, correctly interpreting and matching the version range? I guess it's certainly doable... but a bit of work - more than I personally have time to sink into, right now.

Next release

While #29 is about regular releases (and should be addressed) I would like to discuss the next release independently from that.

There are two main things to discuss:

  1. version
  2. release process

Regarding 1:

#92 suggest different versions for JDK8/11, this seems to be a good idea, but I have to idea how to solve that short-term. Since the current code (after #93 ) targets JDK11 I would suggest to focus on a JDK11-release. Since we still have semver-versioning, I would we should increase the version to 2.0.0 and keep that for all artifacts. . I would then suggest to go on with 2.1.0-SNAPSHOT afterwards.

Regarding 2:

I can prepare a PR to increase the version to what ever we decide in (1), do the release build, and a second PR for the next development version. What needs to be figured out is how the release can be uploaded to Maven Central. I have only done releases to bintray in the past.

"Incomplete" annotations

E.g. Map.computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction):

The return value is either the @NonNull value already present in the map or the result of mappingFunction, which is allowed to return null. Then the return-value of computeIsAbsent is also null. Our current annotation is

computeIfAbsent
 (TK;Ljava/util/function/Function<-TK;+TV;>;)TV;
 (TK;L1java/util/function/Function<-TK;+T0V;>;)T0V;

Which is in general correct. However the eclipse compiler is not able to infer @NonNull if the mappingFunction has a @NonNullreturn value, e.g. Map.computeIfAbsent(key, k -> new Foo());.

computeIfAbsent
 (TK;Ljava/util/function/Function<-TK;+TV;>;)TV;
 (TK;L1java/util/function/Function<-TK;+T0V;>;)TV;

is not working, because then return Map.computeIfAbsent(key, k -> null); passes, even if the return-value of the method is annotated @NonNull.

computeIfAbsent
 (TK;Ljava/util/function/Function<-TK;+TV;>;)TV;
 (TK;L1java/util/function/Function<-TK;+TV;>;)TV;

is not working either, because then the compiler requires the mappingFunction to have a @NonNull return value.

Another problem is that

Stream<@NonNull T> = Stream<@Nullable T>.filter(Objects::nonNull);

is not working, because the compiler is not able to detect that all null-objects will be filtered by .filter(Objects::nonNull).

Has anyone any idea how to solve that?

Headless examples needs updating

I could not get the tycho compiler version to work at all.

This is for others but this works for me:

    <profile>
      <id>eclipse</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <compilerId>eclipse</compilerId>
              <!-- 
              You need to use compilerArguments here instead of compilerArgs despite it being deprecated 
              -->
              <compilerArguments>
                <properties>${parent.root}/etc/eea/prefs/org.eclipse.jdt.core.prefs</properties>
                <!-- Apparently CLASSPATH is the only one that works -->
                <annotationpath>CLASSPATH</annotationpath>
                <!-- Because classpath is the only that works we add our eea directory to it -->
                <classpath>${parent.root}/etc/eea</classpath>
              </compilerArguments>
              <showWarnings>true</showWarnings>
              <showDeprecation>true</showDeprecation>
              <failOnWarning>true</failOnWarning>
              <failOnError>true</failOnError>
            </configuration>
            <!-- 
            Maven will try patch in modules for unit test which breaks the eclipse compiler
            Fatal error compiling: Failed to run the ecj compiler: Unrecognized option : patch-module
            The patch module above has two hyphens in front of it.
            -->
            <executions>
              <execution>
                <id>default-testCompile</id>
                <phase>none</phase>
              </execution>
            </executions>
            <dependencies>
              <dependency>
                <groupId>org.codehaus.plexus</groupId>
                <artifactId>plexus-compiler-eclipse</artifactId>
                <version>2.13.0</version>
              </dependency>
              <dependency>
                <groupId>org.eclipse.jdt</groupId>
                <artifactId>ecj</artifactId>
                <version>3.34.0</version>
              </dependency>
            </dependencies>
          </plugin>
        </plugins>
      </build>
    </profile>

I don't use lastnpe augmented annotation jar but my own copy. I just copy all the annotations to new projects. Yes that sucks but it is easier to augment it.

Version the JDK EEA set

Instead of trying to pile all of the JDK annotations into a single global set, create versioned packages for each major JDK release (8, 11, etc) and possibly build annotations built on delta files between releases.

Maven central deployment v0.0.1

set up the infrastructure to be able to deply org.lastnpe EEA JARs to Maven central

manually, for now (automate it later)

Improve Documentation

I come here on a regular basis every few months, to see if I can integrate that into some projects. But so far I always failed (I gave up pretty quickly).
The example project uses as parent org.lastnpe.eea.eea-root
Can I just ignore that and only add it as a dependency?
Is really everything in the plugin section needed? I guess the tycho compiler stuff is not needed for a normal project?

hello and lib uses as parent org.lastnpe.examples. I guess I can just add org.lastnpe.eea.eea-all as dependency and all the plugin configuration from org.lastnpe.examples?

Hello but not lib uses

    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-deploy-plugin</artifactId>
        <configuration>
          <skip>true</skip>
        </configuration>
      </plugin>
    </plugins>

what would be the difference there?

A minimal example, with a completely independent project which doesn't use org.lastnpe.eea.eea-root as parent would make things easier for people which are no maven mages.

What is the meaning of + in EEA files?

I'm currently merging some EEA files and wonder about the additional "+" sign in EEA files, for example https://github.com/lastnpe/eclipse-null-eea-augments/blob/master/libraries/java/java/util/Collection.eea#L7. I noticed this "+" is added together with the normal "0" or "1" when using the menus to annotate something. But what is the exact meaning? And under which circumstances does it get added?

Addendum: And should we consider it a bug that the newly added "+" sign is not deleted again when removing the nullness/nonnull annotation? That is how such a single "+" sign as shown above get's into the EEA files: Add an annotation and remove it again, and only the + remains...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.