Search code examples
javamavenmoduledependencies

Add non-modular dependancy in modular project


I am pretty new to the system of the modular project. For the context, I began a JavaFX project in version 17 and I have now a module-info.java file that I never heard before. With more informations I begin to understand how it works. But I have an issue.

In my project I use Maven and I add this dependency :

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations</artifactId>
    <version>24.0.1</version>
    <scope>compile</scope>
</dependency>

I want to use the @NotNull, @Nullable etc... annotations in my project. But when I try to use it I have this error when I run :

java: cannot find symbol
  symbol:   class NotNull
  location: class be.machigan.dvdindexer.services.DVDFolder

So I was thinking of add it to the module-info.java file like this :

module DVDIndexer {
    requires javafx.controls;
    requires javafx.fxml;
    requires com.google.gson;
    requires org.jetbrains.annotations; // <- here

    opens be.machigan.dvdindexer to javafx.fxml, com.google.gson;
    opens be.machigan.dvdindexer.services to com.google.gson;
    exports be.machigan.dvdindexer;
    exports be.machigan.dvdindexer.controllers;
    opens be.machigan.dvdindexer.controllers to javafx.fxml;
}

But when I run it, I have this error :

java: module not found: org.jetbrains.annotations

And whith that error the annotations isn't recognized by the IDE (like the other situation above).

I have search on Internett and I have learn that the error can occurs because of the dependency doesn't have a module-info.class file. But I search on the Github of the dependency and there is a module-info.java. Here.

And even that, for the futur I don't know how to add a dependency that doesn't have a module-info.java.

Thanks in advance for the help !


Solution

  • Your problem is not related to using non-modular dependencies in a modular context. As you've discovered, the dependency in question is modular; it has a module-info descriptor. And the name of this module is org.jetbrains.annotations.

    The problem is that the dependency is a compile-time only dependency. You've explicitly marked it as such by using <scope>compile</scope> in your POM file1. That means Maven will place the dependency on the module-path at compile-time but not at run-time. This leads to an error because you have:

    requires org.jetbrians.annotations;
    

    That tells the Java Platform Module System that the org.jetbrains.annotations module is required by the DVDIndexer module at both compile-time and run-time. To solve this problem, you need to have the following directive instead:

    requires static org.jetbrains.annotations;
    

    The static keyword in this context means the required module is optional at run-time (but still required at compile-time). The main purpose of this feature is to allow a module to require another module at compile-time without forcing said other module to be present at run-time. In other words, it allows for compile-time only dependencies.


    1. This is a good thing. The java-annotations library is designed to be a compile-time only dependency. Its purpose is to provide better documentation and possibly allow code analyzers to better analyze code for potential errors. But the library itself defines no run-time behavior, and the annotations all have a retention policy of CLASS (meaning they are not visible via reflection). Thus, there's no reason to require the dependency at run-time.