├── .gitignore ├── README.md ├── devday-service ├── pom.xml └── src │ └── main │ └── java │ ├── de │ └── consol │ │ └── devday │ │ └── service │ │ └── EventService.java │ └── module-info.java ├── devday-talk-service ├── pom.xml └── src │ ├── main │ └── java │ │ ├── de │ │ └── consol │ │ │ └── devday │ │ │ └── talk │ │ │ └── service │ │ │ └── TalkService.java │ │ └── module-info.java │ └── test │ └── java │ └── de │ └── consol │ └── devday │ └── talk │ └── service │ └── TalkServiceTest.java ├── devday-workshop-service ├── pom.xml └── src │ ├── main │ └── java │ │ ├── de │ │ └── consol │ │ │ └── devday │ │ │ └── workshop │ │ │ └── service │ │ │ └── WorkshopService.java │ │ └── module-info.java │ └── test │ └── java │ └── de │ └── consol │ └── devday │ └── workshop │ └── service │ └── WorkshopServiceTest.java ├── devday ├── pom.xml └── src │ ├── main │ └── java │ │ ├── de │ │ └── consol │ │ │ └── devday │ │ │ ├── Devday.java │ │ │ └── markdown │ │ │ └── MarkdownService.java │ │ └── module-info.java │ └── test │ └── de.consol.devday │ └── de │ └── consol │ └── devday │ └── markdown │ └── MarkdownServiceTest.java ├── pom.xml ├── run.cmd └── run.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | target 3 | 4 | # Mobile Tools for Java (J2ME) 5 | .mtj.tmp/ 6 | 7 | # Package Files # 8 | *.jar 9 | *.war 10 | *.ear 11 | 12 | # IntelliJ 13 | *.iml 14 | .idea 15 | 16 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 17 | hs_err_pid* 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Java 9 Modules Example with Maven and JUnit 2 | This simple project shows how Maven can be used to build Java 9 modules. 3 | 4 | It uses the `ServiceLoader` to load loosely coupled services from other modules. 5 | It also demonstrates how methods in non-exported packages can be unit-tested from the 6 | Unnamed Module simply by *not* modularizing the test sources. 7 | 8 | 9 | Read more in our blog post: [Getting Started with Java 9 Modules] 10 | 11 | ## Prerequisites: 12 | * Maven >= 3.0.0 13 | * JDK 9 14 | 15 | ## Running the example 16 | * `mvn clean package` 17 | * `.\run.cmd` or `./run.sh` 18 | 19 | ## Known issues 20 | * At the moment, the project does not compile in Eclipse due to a known issue in JDT. See this [thread on the m2e-users mailing list for more details and a workaround]. 21 | 22 | [Getting Started with Java 9 Modules]: https://labs.consol.de/development/2017/02/13/getting-started-with-java9-modules.html 23 | [thread on the m2e-users mailing list for more details and a workaround]: https://dev.eclipse.org/mhonarc/lists/m2e-users/msg05698.html 24 | -------------------------------------------------------------------------------- /devday-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | de.consol 9 | java9-modules-example 10 | 1.0-SNAPSHOT 11 | 12 | 13 | devday-service 14 | 15 | 16 | 17 | org.assertj 18 | assertj-core 19 | 2.1.0 20 | test 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /devday-service/src/main/java/de/consol/devday/service/EventService.java: -------------------------------------------------------------------------------- 1 | package de.consol.devday.service; 2 | 3 | import java.util.List; 4 | 5 | public interface EventService { 6 | 7 | public List getEvents(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /devday-service/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module de.consol.devday.service { 2 | 3 | exports de.consol.devday.service; 4 | 5 | } -------------------------------------------------------------------------------- /devday-talk-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | de.consol 9 | java9-modules-example 10 | 1.0-SNAPSHOT 11 | 12 | 13 | devday-talk-service 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 18 | de.consol 19 | devday-service 20 | ${project.version} 21 | 22 | 23 | junit 24 | junit 25 | 4.12 26 | test 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /devday-talk-service/src/main/java/de/consol/devday/talk/service/TalkService.java: -------------------------------------------------------------------------------- 1 | package de.consol.devday.talk.service; 2 | 3 | import de.consol.devday.service.EventService; 4 | 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.Stream; 8 | 9 | public class TalkService implements EventService { 10 | 11 | public List getEvents() { 12 | return Stream.of( 13 | "Deep Learning", 14 | "Java 9 Modules in a Nutshell", 15 | "Containerized End-2-End-Testing and Monitoring", 16 | "JavaScript Lightning Talks", 17 | "Citrus & Microservices (Kubernetes)", 18 | "Apache Cassandra vs. MongoDB" 19 | ) 20 | .map(TalkService::prefix) 21 | .collect(Collectors.toList()); 22 | } 23 | 24 | static String prefix(String input) { 25 | return "Talk: " + input; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /devday-talk-service/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module de.consol.devday.talk.service { 2 | 3 | requires de.consol.devday.service; 4 | 5 | exports de.consol.devday.talk.service; 6 | 7 | provides de.consol.devday.service.EventService 8 | with de.consol.devday.talk.service.TalkService; 9 | } -------------------------------------------------------------------------------- /devday-talk-service/src/test/java/de/consol/devday/talk/service/TalkServiceTest.java: -------------------------------------------------------------------------------- 1 | package de.consol.devday.talk.service; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class TalkServiceTest { 7 | 8 | @Test 9 | public void testGetEvents() { 10 | TalkService ts = new TalkService(); 11 | Assert.assertEquals(6,ts.getEvents().size()); 12 | } 13 | 14 | @Test 15 | public void testPrefix() { 16 | Assert.assertEquals(TalkService.prefix("blah blah"), "Talk: blah blah"); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /devday-workshop-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | de.consol 9 | java9-modules-example 10 | 1.0-SNAPSHOT 11 | 12 | 13 | devday-workshop-service 14 | 15 | 16 | 17 | de.consol 18 | devday-service 19 | ${project.version} 20 | 21 | 22 | junit 23 | junit 24 | 4.12 25 | test 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /devday-workshop-service/src/main/java/de/consol/devday/workshop/service/WorkshopService.java: -------------------------------------------------------------------------------- 1 | package de.consol.devday.workshop.service; 2 | 3 | import de.consol.devday.service.EventService; 4 | 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.Stream; 8 | 9 | public class WorkshopService implements EventService { 10 | 11 | public List getEvents() { 12 | return Stream.of( 13 | "Kubernetes", 14 | "Gamification" 15 | ) 16 | .map(WorkshopService::prefix) 17 | .collect(Collectors.toList()); 18 | } 19 | 20 | static String prefix(String input) { 21 | return "Workshop: " + input; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /devday-workshop-service/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module de.consol.devday.workshop.service { 2 | 3 | requires de.consol.devday.service; 4 | 5 | exports de.consol.devday.workshop.service; 6 | 7 | provides de.consol.devday.service.EventService 8 | with de.consol.devday.workshop.service.WorkshopService; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /devday-workshop-service/src/test/java/de/consol/devday/workshop/service/WorkshopServiceTest.java: -------------------------------------------------------------------------------- 1 | package de.consol.devday.workshop.service; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class WorkshopServiceTest { 7 | 8 | @Test 9 | public void testGetEvents() { 10 | WorkshopService ts = new WorkshopService(); 11 | Assert.assertEquals(2,ts.getEvents().size()); 12 | } 13 | 14 | @Test 15 | public void testPrefix() { 16 | Assert.assertEquals(WorkshopService.prefix("blah blah"), "Workshop: blah blah"); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /devday/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | de.consol 9 | java9-modules-example 10 | 1.0-SNAPSHOT 11 | 12 | 13 | devday 14 | 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-jar-plugin 20 | 21 | 22 | 23 | true 24 | lib/ 25 | de.consol.devday.Devday 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | de.consol 36 | devday-service 37 | 1.0-SNAPSHOT 38 | 39 | 40 | junit 41 | junit 42 | 4.12 43 | test 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /devday/src/main/java/de/consol/devday/Devday.java: -------------------------------------------------------------------------------- 1 | package de.consol.devday; 2 | 3 | import de.consol.devday.service.EventService; 4 | import de.consol.devday.markdown.MarkdownService; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.ServiceLoader; 9 | 10 | public class Devday { 11 | 12 | private static List eventServices = new ArrayList<>(); 13 | private static MarkdownService markdownService = new MarkdownService(); 14 | 15 | public static void main(String[] args) { 16 | System.out.println(""); 17 | System.out.println("ConSol Devday Schedule"); 18 | System.out.println("======================"); 19 | 20 | ServiceLoader.load(EventService.class).forEach(eventServices::add); 21 | 22 | List events = new ArrayList<>(); 23 | 24 | eventServices.stream() 25 | .map(EventService::getEvents) 26 | .forEach(events::addAll); 27 | 28 | System.out.println(markdownService.formatList(events)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /devday/src/main/java/de/consol/devday/markdown/MarkdownService.java: -------------------------------------------------------------------------------- 1 | package de.consol.devday.markdown; 2 | 3 | import de.consol.devday.service.EventService; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | 9 | public class MarkdownService { 10 | 11 | private static List eventServices = new ArrayList<>(); 12 | 13 | public String formatList(List events) { 14 | return events.stream() 15 | .map((e) -> "* " + e) 16 | .collect(Collectors.joining("\n")); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /devday/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module de.consol.devday { 2 | 3 | requires de.consol.devday.service; 4 | 5 | uses de.consol.devday.service.EventService; 6 | 7 | } -------------------------------------------------------------------------------- /devday/src/test/de.consol.devday/de/consol/devday/markdown/MarkdownServiceTest.java: -------------------------------------------------------------------------------- 1 | package de.consol.devday.markdown; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.util.List; 7 | 8 | public class MarkdownServiceTest { 9 | 10 | @Test 11 | public void formatList() { 12 | MarkdownService service = new MarkdownService(); 13 | List abc = List.of("a", "b", "c"); 14 | assertThat(service.formatList(abc)).isEqualTo("* a\n"); 15 | Assert.assertEquals("* a\n* b\n* c", service.formatList(abc)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | de.consol 8 | java9-modules-example 9 | 1.0-SNAPSHOT 10 | pom 11 | 12 | 13 | UTF-8 14 | 1.9 15 | 1.9 16 | 17 | 18 | 19 | devday 20 | devday-service 21 | devday-workshop-service 22 | devday-talk-service 23 | 24 | 25 | 26 | 27 | 28 | org.apache.maven.plugins 29 | maven-compiler-plugin 30 | 3.7.0 31 | 32 | 9 33 | 9 34 | true 35 | true 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /run.cmd: -------------------------------------------------------------------------------- 1 | java --module-path devday-service\target\devday-service-1.0-SNAPSHOT.jar;devday\target\devday-1.0-SNAPSHOT.jar;devday-workshop-service\target\devday-workshop-service-1.0-SNAPSHOT.jar;devday-talk-service\target\devday-talk-service-1.0-SNAPSHOT.jar -m de.consol.devday/de.consol.devday.Devday 2 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | $JDK_HOME/bin/java --module-path devday-service/target/devday-service-1.0-SNAPSHOT.jar:devday/target/devday-1.0-SNAPSHOT.jar:devday-workshop-service/target/devday-workshop-service-1.0-SNAPSHOT.jar:devday-talk-service/target/devday-talk-service-1.0-SNAPSHOT.jar -m de.consol.devday/de.consol.devday.Devday 3 | --------------------------------------------------------------------------------