I'm making a project using lombok. The structur of it is:
Main project:
module A
module B
module C
I created a main function in module A to test the program.
Module A depends on module B and C, module B on anything and module C on module A and B (don't know if this is important to know).
When I run the main function on module A it gives me an error:
Error:java: Annotation processing is not supported for module cycles. Please ensure that all modules from cycle [A,B,C] are excluded from annotation processing
I think it is caused by lombok. Anyone knows how to solve it?
Related
I'm having a multi module Java project. To test specific constraints, I'm using Arch Unit. This works fine for the classes that are in the same module as the Arch Unit test class. However, I'd like to write one Arch Unit test that tests classes from all the modules in my project.
How can I import all classes from all the modules I have?
A module is a package of java packages. Let's say you have modules 'A' and 'B' and inside them you have packages 'a' and 'b' respectively, and inside of packages you have classes 'A.java' and 'B.java' respectively.
If you need to use class 'A.java' from module 'A' inside of module 'B' first you need to edit 'module-info.java' file of module 'B'. It's location is at the root of the module and it will look like this:
module B {
requires A;
}
Now, module 'B' has both a runtime and a compile-time dependency on module 'A'
and all public types exported from a dependency are accessible by our module when we use this directive.
In the 'module-info.java' file of module 'A' you need to write:
module A {
exports a;
}
For more detailed info refer to java modules guide
I wrote a Java module a.b.c and another module d.e.f that requires a.b.c. I'm using IntelliJ.
First module's module-info.java:
module a.b.c {
exports a.b.c;
requires org.jfree.jfreechart;
requires commons.cli;
requires java.desktop;
requires java.net.http;
}
Second module's module-info.java:
module d.e.f {
requires a.b.c;
requires org.json;
}
Both modules compile. When I run d.e.f, I get the following error.
java.lang.module.ResolutionException: Module a.b.c contains package org.jfree.chart.ui, module org.jfree.jfreechart exports package org.jfree.chart.ui to a.b.c
These modules aren't split as there is no redundant package between them.
What does this message mean?
How do I resolve it?
I received the ResolutionException error because my IntelliJ project was not set up correctly. The best guidance I found was at Java 9 Modules with IntelliJ IDE Quick Start. Both modules now run without any compile- or run-time errors.
I have a Maven project with two Maven modules A and B. A contains the following Java module definition:
module A {
exports internal.util to B;
exports external.A;
}
B contains the following Java module definition:
module B {
requires A;
exports external.B;
}
When I build the project, I get an error:
[WARNING] module-info.java:[16,106] module not found: B
Module B exists but because Module A is compiled before B and does not depend on it, the compiler has no way of knowing that. Because I configured the compiler to treat warnings as errors (-Werror), the build fails.
Seeing as I want to keep treating warnings as errors, what is the best way to resolve this problem?
Is there a way to hint to the compiler that this module will be declared in the future?
Is there a way to suppress all warnings of this type?
I figured out a workaround by scanning through the JDK 11 source-code: -Xlint:-module. I am still open to a better solution if someone finds one.
UPDATE: An alternative is to use --module-source-path as demonstrated by https://stackoverflow.com/a/53717183/14731
Thank you Alan Bateman for pointing me in this direction!
As I could infer from the question, your scenario is such that both the module A and B co-exists and the module A does not depend on the module B.
From a module system prospect, since A makes a qualified export to the module B, a warning is thrown if the module B is not resolved on the modulepath while you build A.
On IntelliJ-IDEA I could fix such an issue by adding a dependency of module B to the module A without any declaration changes. Though using the Maven framework, I couldn't imagine something without a cyclic dependency here, maybe the suggestion by khmarbaise could help.
Note: An alternate way to fix this though could also be to disable such warnings using the command-line arg :
-Xlint:-exports
Or as Alan points out for correction
-Xlint:-module
Thinking out loud, that would be since, the warning is a result of a qualified export, but about a module not found.
Useful: You could find the details over these command line args with javac command.
I have a project like this:
\---main
\---src
\---com.foo
\---UnnamedStart.java
\---api
\---src
\---com.foo.api
\---ApiInterface.java
\---module-info.java
\---impl
\---src
\---com.foo.impl
\---ApiInterfaceImpl.java
\---module-info.java
Implementatio of UnnamedStart.java is:
public static void main(String[] args) {
ServiceLoader<ApiInterface> services = ServiceLoader.load(ApiInterface.class);
...
}
Note that main is unnamed module.
api/src/module-info.java is:
module com.foo.api {
exports com.foo.api;
}
and impl/src/module-info.java is:
update 1.1 - code below updated see comments, added requires
update 1.2 - code below updated, provides A with B changed to provides B with A mistake during creating question, originally was ok
module com.foo.impl {
requires com.foo.api; //added (update 1.1)
provides com.foo.impl.ApiInterface
with com.foo.api.ApiInterfaceImpl; //vice versa (update 1.2)
}
When I run my code in UnnamedStart.java I end up with no element in services.
I also tried to create a static method in com.foo.api.ApiInterface:
static List<ApiInterface> getInstances() {
ServiceLoader<ApiInterface> services = ServiceLoader.load(ApiInterface.class);
List<ApiInterface> list = new ArrayList<>();
services.iterator().forEachRemaining(list::add);
return list;
}
and add in api/src/module-info.java line uses com.foo.api.ApiInterface; but it gave the same result (nothing).
The only way I made it work is by migrating main from unnamed to named module.
1. How does java 9 work when unnamed module trying to interact with named module?
2. Does it possible to make it work and keeping the main like unnamed module?
update 1.3 - added related project
ServiceLoader::load works as usual, but the are other things.
[Short answer]
1. Unnamed module reads the same like named module to named module, but named module can not access types in the unnamed module.
2. You are trying to launch an application from a non-modular JAR so you have to explicitly resolve required modules by --add-modules com.foo.impl.
Note that your required modules have to be on module graph (e.g. add by --module-path).
[More details]
1. There are 4 different types of modules: built-in platform module, named module, automatic module, unnamed module and each of them are named apart from unnamed module
As they wrote the unnamed module treats all the other modules the same like named module:
All other modules have names, of course, so we will henceforth refer to those as named modules.
The unnamed module reads every other module. [...]
The unnamed module exports all of its packages. [...] It does not, however, mean that code in a named module can access types in the unnamed module. A named module cannot, in fact, even declare a dependence upon the unnamed module.
[...]
If a package is defined in both a named module and the unnamed module then the package in the unnamed module is ignored.
Even an automatic module indeed is also named:
An automatic module is a named module that is defined implicitly, since it does not have a module declaration.
2. Second part of this answer
If you compile non-modular code or launch an application from a non-modular JAR, the module system is still in play and because non-modular code does not express any dependencies, it will not resolve modules from the module path.
So if non-modular code depends on artifacts on the module path, you need to add them manually with the --add-modules option. Not necessarily all of them, just those that you directly depend on (the module system will pull in transitive dependencies) - or you can use ALL-MODULE-PATH (check the linked post, it explains this in more detail).
This #nullpointer comment will be useful
Also, the module resolution still needed the impl to be resolved during the startup. To check which you could also make use of the --show-module-resolution flag.
I've read a lot of questions & answers in SO, without any luck. Example: Module packages not found at compile time in IntelliJ
The thing is that I've a project which formed by:
Module A
Module B
Module C
Module B has a dependency with module A and module C.
So the imports in module B, to code are like
import com.moduleA.Fragment1;
import com.moduleA.Fragment2;
import com.moduleA.SomeInterface;
Those lines are correctly imported in "coding-time", I can work with those classes correctly.
However when I do compile, it crashes with a:
Error:(8, 32) error: com.moduleA does not exist
I've tried adding this module A as Android Library but it's not OK for me, because Android requires generating constants fields (http://tools.android.com/tips/non-constant-fields).
I don't know what else to do.
Any tips?
Sorry for the people who asked for an example of code, but it was as basic as that, with a Gradle build.
I fixed the issue by creating a library project within my project. So module A is actually a Library.
I said that I couldn't use library because of the non-constant-field, but that error was generated by AndroidAnnotations, which explains how to create library modules with it:
https://github.com/excilys/androidannotations/wiki/Library-projects#referencing-ids-by-name
Thanks.