Java 9 Modules and JUnit 4
Asked Answered
H

3

7

Eclipse oxygen; windows 7; JDK 9 final from 9, 21; JUnit 4.12 and an existing application. As starting point the application can be compiled, executed and all JUnit Tests shows green. Now we use eclipse to generate the file module-info.java. The outcome looks like:

module ch.commcity.topsort {
   exports ch.commcity.topsort;

   requires junit;
}

But with the error: junit cannot be resolved to module. The question is: How to tell the file that junit does not define any module and it should be run in compatibility mode?

Heartbeat answered 27/9, 2017 at 20:37 Comment(1)
what framework are you using in your project? maven / gradle etc? Also which version of Eclipse oxygen?Straightforward
M
8

How to tell the file that junit does not define any module and it should be run in compatibility mode?

Your question seems to be based on several misconceptions:

  • You can not tell module-info.java whether JUnit defines a module or not. If a module says it requires another module then the compiler expects that module to be present - no way around that.
  • Whether JUnit 4 comes as a module or not is not overly important - as long as you place it on the module path, it will end up being treated as a module (possibly as an automatic one).
  • There is no "compatibility mode". You can continue to write code as you did before the module system (almost), but once you're creating module declarations you need to play by its rules.

I recommend to give the outstanding State of the Module System a thorough read and then ask yourself what exactly you are trying to accomplish. Are you really trying to create a module that depends on JUnit? Or was that just accidental because you use its API for testing. If the latter, you should not depend on it - instead your IDE / build tool needs to figure out how to compile and run your tests.

Expansion on "a module that depends on JUnit"

The module system does not classify dependencies as "compile" or "test" - if a module requires another module, it has to be present, always. That means a module that requires junit would force the presence of JUnit. Unless the module provides testing-related features, that is most certainly wrong.

In other words, requires junit is akin to adding JUnit to a project's POM, using the compile scope.

Mickey answered 28/9, 2017 at 8:31 Comment(10)
I'm sorry Nicolai, none of your assumption is correct. Look at my question. We have a little project "topsort". Built 10 years ago with Java 5 or 6. Now we have java 9. We compile and we run the JUnit tests to green. Fine! Now we go a step further. We use eclipse to generate the module-info.java file. This would allow us to have the topsort algorithm defined as a module for future use. So eclipse generate the file defining the module "topsort" and defining the dependency of JUnit for tests. But JUnit seems not to be on the module path. Why, and how to correct is the question.Heartbeat
It would help if you could point out which of my "assumptions" are incorrect - all three bullet points are rock solid and the rest are largely questions. You write "So eclipse generate the file defining the module 'topsort' and defining the dependency of JUnit for tests" - unless topsort is a testing library, you don't want that dependency in there. I edited my answer to provide an explanation.Mickey
I'm speaking about your assumptions w.r.t. my problem. You mention pom. It's not a maven project. An ant script exist to test and to build the jar. I repeat, the question is how to tell eclipse to put the JUnit library on the module path. I just read something about to toggle in the build path the entry Module:No to read Module:Yes. I tried that in the user Library definition of junit.jat and org.hamcrest.core_1.3.0v... I have found such an entry, but nothing can be toggled. I use the patches for Oxygen: 1.1.1.v20170826-0521_BETA_JAVA9 and 1.1.1.v20170826-0521_BETA_JAVA9.Heartbeat
I do not assume you have a Maven project, I use it as an example to clarify why requiring junit is most certainly wrong (and we didn't even talk about the fact that no library should be published that references a module by the name derived from its file name). I did assume that "topsort" (can you link to the project?) is not a testing-related library. If that's correct, the answer stands.Mickey
JUnit is a testing framework. I wonder how you conclude that the eclipse generated requires definition "junit" in the module-info.java file is derived from the file name. Not a rock solid assumption and in any case not relevant at all. I suspect the eclipse BETA plugin for Java9 still having some bugs. It's Beta, so what. I published the case with my only goal to find someone already knowing how to circumvent the issue. That's the point.Heartbeat
"I wonder how you conclude that the eclipse generated requires definition 'junit' in the module-info.java file is derived from the file name." Because I know how automatic modules work. Yes, the Eclipse plugin may have bugs, but unless "topsort" is a testing library, you're still doing the wrong thing depending on JUnit.Mickey
Sorry Nicolai your comment isn't helpful. You try to teach without knowing. I'm used since ever to hide every thing not required to be visible from outside, using public very restrictively. You can't test a class with package visibility only, unless your testclass sits in the same package. Doesn't hurt. It's easy with Ant or Maven to build what you want. Eclipse prone to allow to set the module path under the property “Java Build Path/Libraries”. I have the most recent Beta plugin, but it doesn't work yet, or any more! I hope the case is not forgotten and will work with Oxygen SP1!Heartbeat
Juerg, if you really want help, then you should accept that other people might know more about the module system than you do - maybe this helps to see where I fit in. My argument is not about Eclipse or about how you organize your code or tests - this is a categorical argument against including test dependencies in your module declaration. If you do that, then all "topsort" users are forced to have JUnit on the module path during regular execution (i.e. not only when testing). Is this really what you want?Mickey
Short answer: remove requires junit; from module-info.java. Longer answer: Your test code does not belong in the resulting runtime jar. So your runtime jar in turn has no dependency on junit. Real answer: try to understand what Nicolai said, he is absolutely right and knows what he is talking about.Lindgren
I agree, that "requires junit" within the module-info.java file rised an issue unknown before. Aparently 2 module-info.java files are required now. One for the testphase, and one to build the distribution without JUnit tests. I'm aware about this, as before! But this is the next step and not the point of the moment. The first goal is to run JUnit tests within eclipse having the file modul-info.java defined, the same way it worked before. It doesn't! The second issue Ant neither works yet. That is the point. I just worry, this will not be corrected until 10.11!Heartbeat
N
4

First, please update your Java 9 support for Eclipse Oxygen or use the latest available release candidate build for Eclipse 4.7.1a (to be released on October 11, 2017).

To add a library or a container to the modulepath of a Java 9 project in Eclipse, open the project's Java Build Path dialog. On the Libraries tab, select the node Modulepath and add your library to it. Make sure to first remove that library from the Classpath node if it is already present there.

As mentioned by others, in your case, the JUnit libraries will be considered as automatic modules.

Modulepath node

Ninurta answered 3/10, 2017 at 8:32 Comment(10)
Be assured, I have the latest available BETA plugin for Java 9. I deteted the froject from eclipse, then I deleted all .x-files like .classpath, .project and the folder .settings on the HD. Then I reopened the project within eclipse. Resulting junit being seen by eclipse now!Heartbeat
I also modified the eclipse.ini file to start with Java 9. This worked so far. I started also the JUnit tests from eclipse. something happened, but without showing a result, nor errors. I tried to use JUnit 5 instead of 4, but this seems to require more adaptions. W.r.t. Ant, ant still fails to compile the module-info.java. Infact, ant still use the Java 8 compiler. Though I tried to tell ant to use java 9 I didn't have success so far. Conclusion, Java 9, modules, + JUnit + ant, seems still to be a challenge. I'm not sure all this issues can be resolved until October 11.Heartbeat
Your picture shows the subitem "Is modular" under Junit. This is missing in my IDE, though I can't get any newer BETA plugin. I have 1.1.1.v20170826-0521_BETA_JAVA9 installed. After 10.11 I'll download 4.7.1(a) and I'll see what changed. Until then I'll keep the other stones rolling up!Heartbeat
@Heartbeat "v20170826" implies that you have the changes from 26 August 2017. I am not sure why you are not able to get newer updates from October 2017. You should probably start with a fresh Eclipse installation and follow the steps from the Eclipse marketplace entry or just download the 4.7.1a RC2 build right now. If you still see any issues then I would suggest opening a bug report for Eclipse.Ninurta
Thanks for the confirmation. I agree. Yes I tried several times to update. Didn't work. I saw the download 4.7.1a RC2, but I didn't download. I'm waiting for 10.11 because I have also C++ plugins for JNI developments. This means some additional work, hence no time to do it twice. Anyway, the aim is to have some experiences with Java 9 and modules. I'll be back next week and if I see problems with my small nice already modular project from 2007, I'll report.Heartbeat
a) Is it possible to add entries to the module path using maven and M2E plugin or b) does this need to be done manually? Until now the pom.xml file was my central place to define the project. Therefore I would prefer to include that information in the pom.xml, too.Quartus
@Heartbeat wondering whether you could make it work? Me not (having oxygen1a and doing exactly as described in this answer) ...the option still seem to be either adding requires junit to the module info or a separate testing module - both very suboptimal. Light on the horizon, maybe bugs.eclipse.org/bugs/show_bug.cgi?id=520713 ?Saundra
@Saundra to tell the truth, I gave up! w.r.t. my first contribution, it was a bug of the beta plugin which is resolved with the version 1a. As long you don’t have the file module-info.java defined, you can append the junit library either 4 or 5 to the classpath or to the module path. The test can be run in either configuration. The next step was to let eclipse generate the file. The content is the export of your module and "requires junit or org.junit.jupiter.api". But now tests can’t be run anymore. It results in “No tests found with test runner ‘Junit 5’”!Heartbeat
You are hitting bugs.eclipse.org/bugs/show_bug.cgi?id=525948 which is targeted to be fixed in Eclipse Oxygen.3 (4.7.3) release.Ninurta
@Saundra the project I checked out to test jigsaw was written first with java 1.4 or older. Ant allowed to do the tests, to generate the reports and javadoc and the distribution jar could be generated clean of junit required for the tests. Until java 8 this still works. But it doesn’t yet for java 9 and not at all with jigsaw. Maven neither can handle the jigsaw case. Hence, there is still a lot of work pending. Anyway java 9 is still not available for Arm 32. May actual battlefield with C++, JNI and java 8! C++ is the wordy hard part of it! :)) Jigsaw is postponed.Heartbeat
S
0

How to tell the file that junit does not define any module and it should be run in compatibility mode?

Since the module junit as generated in the would be an automatic module converted from its artifact. You need to make sure that the jar for Junit junit:junit:4.12 is available on the modulepath of your project and the module would be resolved itself.

In order to make sure of the above, you can check dependencies of your project/module as configured in the IDE to include junit:4.12:jar.

Straightforward answered 28/9, 2017 at 4:6 Comment(3)
JUnit is on the classpath of the IDE, otherwise the tests would not be green! But obviously it's not on the classpath w.r.t. module definition. Hence the question is how it can be checked, and where it can be configured. Of course I can wait until October 11 and the outcome of SP1 for Oxygen, hopefully then the bug is gone. Nevertheless I'm curious to know if it can be fixed before.Heartbeat
It would have to be on the module path to become an automatic module.Mickey
@Nicolai Yup, corrected. from classpath would anyway had been an unnamed module.Straightforward

© 2022 - 2024 — McMap. All rights reserved.