├── .gitignore ├── README.md ├── chapter10 ├── generate_moduledescriptor │ ├── README.md │ ├── addmoduledescriptor.sh │ ├── build.sh │ └── src │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── com │ │ └── javamodularity │ │ └── mylibrary │ │ ├── MyLibrary.java │ │ └── internal │ │ └── Util.java ├── generate_moduledescriptors_jackson │ ├── README.md │ ├── generate.sh │ ├── jackson-annotations-2.8.7.jar │ ├── jackson-core-2.8.7.jar │ └── jackson-databind-2.8.7.jar ├── modulename │ ├── README.md │ ├── run.sh │ └── src │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── modulename │ │ └── Main.java └── multirelease │ ├── README.md │ ├── run.sh │ └── src │ ├── META-INF │ ├── MANIFEST.MF │ └── versions │ │ └── 9 │ │ └── mrlib │ │ └── Helper.java │ └── mrlib │ ├── Helper.java │ └── Main.java ├── chapter11 ├── multi-module │ ├── README.md │ ├── algorithm.api │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── algorithm │ │ │ │ └── api │ │ │ │ ├── Analyzer.java │ │ │ │ ├── Preprocessing.java │ │ │ │ └── SyllableCounter.java │ │ │ └── module-info.java │ ├── algorithm.coleman │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── algorithm │ │ │ │ └── coleman │ │ │ │ └── ColemanAnalyzer.java │ │ │ └── module-info.java │ ├── algorithm.kincaid │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── algorithm │ │ │ │ └── kincaid │ │ │ │ └── KincaidAnalyzer.java │ │ │ └── module-info.java │ ├── algorithm.naivesyllablecounter │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── algorithm │ │ │ │ └── naivesyllablecounter │ │ │ │ └── NaiveSyllableCounter.java │ │ │ └── module-info.java │ ├── algorithm.nextgensyllablecounter │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── algorithm │ │ │ │ └── nextgensyllablecounter │ │ │ │ └── SyllableCounter3Wrapper.java │ │ │ └── module-info.java │ ├── cli │ │ ├── README.adoc │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ ├── javamodularity │ │ │ │ └── easytext │ │ │ │ │ └── cli │ │ │ │ │ └── Main.java │ │ │ └── module-info.java │ │ │ └── resources │ │ │ └── test.txt │ ├── gui │ │ ├── gui.iml │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── gui │ │ │ │ └── Main.java │ │ │ └── module-info.java │ ├── pom.xml │ └── run.sh └── single-module │ ├── README.md │ ├── my-app.iml │ ├── pom.xml │ ├── run.sh │ └── src │ └── main │ └── java │ ├── javamodularity │ └── maven │ │ └── example │ │ ├── Book.java │ │ └── Main.java │ └── module-info.java ├── chapter12 ├── blackbox │ ├── README.md │ ├── lib │ │ ├── hamcrest-core-1.3.jar │ │ └── junit-4.12.jar │ ├── run.test.junit.sh │ ├── run.test.sh │ ├── src-test │ │ ├── easytext.syllablecounter.junit │ │ │ ├── javamodularity │ │ │ │ └── easytext │ │ │ │ │ └── test │ │ │ │ │ └── JUnitTestSyllableCounter.java │ │ │ └── module-info.java │ │ └── easytext.syllablecounter.test │ │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── test │ │ │ │ └── TestSyllableCounter.java │ │ │ └── module-info.java │ └── src │ │ └── easytext.syllablecounter │ │ ├── javamodularity │ │ └── easytext │ │ │ └── syllablecounter │ │ │ ├── SimpleSyllableCounter.java │ │ │ └── vowel │ │ │ └── VowelHelper.java │ │ └── module-info.java └── whitebox │ ├── README.md │ ├── lib │ ├── hamcrest-core-1.3.jar │ └── junit-4.12.jar │ ├── run.test.junit.classpath.sh │ ├── run.test.junit.modulepath.sh │ ├── src-test │ └── javamodularity │ │ └── easytext │ │ └── syllablecounter │ │ └── vowel │ │ └── JUnitTestVowelHelper.java │ └── src │ └── easytext.syllablecounter │ ├── javamodularity │ └── easytext │ │ └── syllablecounter │ │ ├── SimpleSyllableCounter.java │ │ └── vowel │ │ └── VowelHelper.java │ └── module-info.java ├── chapter2 ├── README.md ├── run.sh └── src │ └── NotInModule.java ├── chapter3 ├── easytext-singlemodule │ ├── README.md │ ├── run.sh │ └── src │ │ └── easytext │ │ ├── javamodularity │ │ └── easytext │ │ │ └── Main.java │ │ └── module-info.java ├── easytext-threemodules │ ├── README.md │ ├── run.sh │ └── src │ │ ├── easytext.analysis │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── FleschKincaid.java │ │ └── module-info.java │ │ ├── easytext.cli │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── cli │ │ │ │ └── Main.java │ │ └── module-info.java │ │ └── easytext.gui │ │ ├── javamodularity │ │ └── easytext │ │ │ └── gui │ │ │ └── Main.java │ │ └── module-info.java ├── easytext-twomodules │ ├── README.md │ ├── run.sh │ └── src │ │ ├── easytext.analysis │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── FleschKincaid.java │ │ └── module-info.java │ │ └── easytext.cli │ │ ├── javamodularity │ │ └── easytext │ │ │ └── cli │ │ │ └── Main.java │ │ └── module-info.java └── helloworld │ ├── README.md │ ├── link.sh │ ├── run.sh │ └── src │ └── helloworld │ ├── com │ └── javamodularity │ │ └── helloworld │ │ └── HelloWorld.java │ └── module-info.java ├── chapter4 ├── easytext-factory │ ├── README.md │ ├── run.sh │ └── src │ │ ├── easytext.analysis.api │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── api │ │ │ │ └── Analyzer.java │ │ └── module-info.java │ │ ├── easytext.analysis.coleman │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── coleman │ │ │ │ └── Coleman.java │ │ └── module-info.java │ │ ├── easytext.analysis.factory │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── factory │ │ │ │ └── AnalyzerFactory.java │ │ └── module-info.java │ │ ├── easytext.analysis.kincaid │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── kincaid │ │ │ │ └── FleschKincaid.java │ │ └── module-info.java │ │ ├── easytext.cli │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── cli │ │ │ │ └── Main.java │ │ └── module-info.java │ │ └── easytext.gui │ │ ├── javamodularity │ │ └── easytext │ │ │ └── gui │ │ │ └── Main.java │ │ └── module-info.java ├── easytext-filtering │ ├── README.md │ ├── run.sh │ └── src │ │ ├── easytext.analysis.api │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── api │ │ │ │ ├── Analyzer.java │ │ │ │ └── Fast.java │ │ └── module-info.java │ │ ├── easytext.analysis.coleman │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── coleman │ │ │ │ └── Coleman.java │ │ └── module-info.java │ │ ├── easytext.analysis.kincaid │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── kincaid │ │ │ │ └── FleschKincaid.java │ │ └── module-info.java │ │ └── easytext.filtering │ │ ├── javamodularity │ │ └── easytext │ │ │ └── filtering │ │ │ └── Main.java │ │ └── module-info.java ├── easytext-services-factory │ ├── README.md │ ├── run.sh │ └── src │ │ ├── easytext.analysis.api │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── api │ │ │ │ └── Analyzer.java │ │ └── module-info.java │ │ ├── easytext.analysis.coleman │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── coleman │ │ │ │ └── Coleman.java │ │ └── module-info.java │ │ ├── easytext.analysis.kincaid │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── kincaid │ │ │ │ └── FleschKincaid.java │ │ └── module-info.java │ │ └── easytext.cli │ │ ├── javamodularity │ │ └── easytext │ │ │ └── cli │ │ │ └── Main.java │ │ └── module-info.java ├── easytext-services │ ├── README.md │ ├── run-cli.sh │ ├── run-gui.sh │ └── src │ │ ├── easytext.analysis.api │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── api │ │ │ │ └── Analyzer.java │ │ └── module-info.java │ │ ├── easytext.analysis.coleman │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── coleman │ │ │ │ └── Coleman.java │ │ └── module-info.java │ │ ├── easytext.analysis.kincaid │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── analysis │ │ │ │ └── kincaid │ │ │ │ └── FleschKincaid.java │ │ └── module-info.java │ │ ├── easytext.cli │ │ ├── javamodularity │ │ │ └── easytext │ │ │ │ └── cli │ │ │ │ └── Main.java │ │ └── module-info.java │ │ └── easytext.gui │ │ ├── javamodularity │ │ └── easytext │ │ │ └── gui │ │ │ └── Main.java │ │ └── module-info.java ├── exampletext.txt └── providers │ ├── README.md │ ├── run.sh │ └── src │ ├── easytext.analysis.api │ ├── javamodularity │ │ └── easytext │ │ │ └── analysis │ │ │ └── api │ │ │ └── Analyzer.java │ └── module-info.java │ ├── main │ ├── javamodularity │ │ └── providers │ │ │ └── main │ │ │ └── Main.java │ └── module-info.java │ ├── provider.factory.example │ ├── javamodularity │ │ └── providers │ │ │ └── factory │ │ │ ├── ExampleProvider.java │ │ │ └── ExampleProviderFactory.java │ └── module-info.java │ └── provider.method.example │ ├── javamodularity │ └── providers │ │ └── method │ │ └── ExampleProviderMethod.java │ └── module-info.java ├── chapter5 ├── cyclic_dependencies │ ├── README.md │ ├── cycle │ │ └── src │ │ │ ├── authors │ │ │ └── Author.java │ │ │ └── books │ │ │ └── Book.java │ └── without_cycle │ │ ├── run.sh │ │ └── src │ │ ├── authors │ │ ├── javamodularity │ │ │ └── authors │ │ │ │ └── Author.java │ │ └── module-info.java │ │ └── books │ │ ├── javamodularity │ │ └── books │ │ │ ├── Book.java │ │ │ └── Named.java │ │ └── module-info.java ├── implied_readability │ ├── README.md │ ├── run.sh │ └── src │ │ ├── easytext.client │ │ ├── easytext │ │ │ └── client │ │ │ │ └── Client.java │ │ └── module-info.java │ │ ├── easytext.domain.api │ │ ├── easytext │ │ │ └── domain │ │ │ │ └── api │ │ │ │ └── Text.java │ │ └── module-info.java │ │ └── easytext.repository.api │ │ ├── easytext │ │ └── repository │ │ │ └── api │ │ │ └── TextRepository.java │ │ └── module-info.java ├── optional_dependencies │ ├── README.md │ ├── run.sh │ └── src │ │ ├── fastjsonlib │ │ ├── javamodularity │ │ │ └── fastjsonlib │ │ │ │ └── FastJson.java │ │ └── module-info.java │ │ └── framework │ │ ├── javamodularity │ │ └── framework │ │ │ ├── Main.java │ │ │ └── MainBad.java │ │ └── module-info.java ├── optional_dependencies_annotations │ ├── README.md │ ├── run.sh │ └── src │ │ ├── application │ │ ├── javamodularity │ │ │ └── application │ │ │ │ ├── BookEntity.java │ │ │ │ └── Main.java │ │ └── module-info.java │ │ └── schemagenerator │ │ ├── javamodularity │ │ └── schemagenerator │ │ │ └── GenerateSchema.java │ │ └── module-info.java ├── optional_dependencies_service │ ├── README.md │ ├── run.sh │ └── src │ │ ├── fastjsonlib │ │ ├── javamodularity │ │ │ └── fastjsonlib │ │ │ │ └── FastJson.java │ │ └── module-info.java │ │ └── framework │ │ ├── javamodularity │ │ └── framework │ │ │ └── Main.java │ │ └── module-info.java ├── resource_encapsulation │ ├── README.md │ ├── run.sh │ └── src │ │ ├── firstresourcemodule │ │ ├── javamodularity │ │ │ └── firstresourcemodule │ │ │ │ ├── ResourcesInModule.java │ │ │ │ ├── ResourcesOtherModule.java │ │ │ │ └── resource_in_package.txt │ │ ├── module-info.java │ │ └── top_level_resource.txt │ │ └── secondresourcemodule │ │ ├── META-INF │ │ └── resource_in_metainf.txt │ │ ├── foo │ │ └── foo.txt │ │ ├── javamodularity │ │ └── secondresourcemodule │ │ │ ├── A.java │ │ │ └── resource_in_package2.txt │ │ ├── module-info.java │ │ └── top_level_resource2.txt └── resourcebundles │ ├── README.md │ ├── run.sh │ └── src │ ├── resourcebundle.dutch │ ├── javamodularity │ │ └── resourcebundle │ │ │ └── dutch │ │ │ ├── DutchTranslationsProvider.java │ │ │ └── Translations_nl.properties │ └── module-info.java │ └── resourcebundle.main │ ├── javamodularity │ └── resourcebundle │ │ ├── Loader.java │ │ ├── Translations_en.properties │ │ └── spi │ │ └── TranslationsProvider.java │ └── module-info.java ├── chapter6 ├── annotated_module │ ├── README.md │ └── src │ │ └── annotated │ │ ├── javamodularity │ │ └── annotatedmodule │ │ │ └── CustomAnnotation.java │ │ └── module-info.java ├── bootlayer │ ├── README.md │ ├── run.sh │ └── src │ │ └── application │ │ ├── javamodularity │ │ └── application │ │ │ └── Main.java │ │ └── module-info.java ├── container │ ├── README.md │ ├── run.sh │ ├── src-appa │ │ └── app.a │ │ │ ├── app │ │ │ ├── NonUniqueName.java │ │ │ └── a │ │ │ │ ├── AppA.java │ │ │ │ └── internal │ │ │ │ └── Worker.java │ │ │ └── module-info.java │ ├── src-appb │ │ └── app.b │ │ │ ├── app │ │ │ ├── NonUniqueName.java │ │ │ └── b │ │ │ │ ├── AppB.java │ │ │ │ └── internal │ │ │ │ └── Worker.java │ │ │ └── module-info.java │ └── src-container │ │ ├── platform.api │ │ ├── module-info.java │ │ └── platform │ │ │ └── api │ │ │ ├── ContainerApplication.java │ │ │ └── tx │ │ │ └── TransactionManager.java │ │ └── platform.container │ │ ├── module-info.java │ │ └── platform │ │ └── container │ │ ├── AppDescriptor.java │ │ ├── Launcher.java │ │ └── tx │ │ └── SimpleTransactionManager.java ├── introspection │ ├── README.md │ ├── run.sh │ └── src │ │ └── javamodularity │ │ └── introspection │ │ └── Introspection.java ├── lookup │ ├── README.md │ ├── run.sh │ └── src │ │ ├── application │ │ ├── javamodularity │ │ │ └── application │ │ │ │ ├── Book.java │ │ │ │ └── Main.java │ │ └── module-info.java │ │ └── ormframework │ │ ├── javamodularity │ │ └── ormframework │ │ │ └── OrmFramework.java │ │ └── module-info.java └── plugins │ ├── README.md │ ├── run.sh │ ├── src-plugina │ └── plugin.a │ │ ├── module-info.java │ │ └── plugina │ │ └── PluginA.java │ ├── src-pluginb │ ├── plugin.b │ │ ├── module-info.java │ │ └── pluginb │ │ │ └── PluginB.java │ └── somelibrary │ │ ├── module-info.java │ │ └── some │ │ └── library │ │ └── Helper.java │ └── src-pluginhost │ ├── pluginhost.api │ ├── module-info.java │ └── pluginhost │ │ └── api │ │ └── Plugin.java │ └── pluginhost │ ├── module-info.java │ └── pluginhost │ └── PluginHostMain.java ├── chapter7 ├── encapsulation │ ├── README.md │ ├── run.sh │ └── src │ │ └── encapsulated │ │ └── EncapsulatedTypes.java ├── jaxb │ ├── README.md │ ├── run.sh │ └── src │ │ └── example │ │ ├── Book.java │ │ └── JaxbExample.java └── removedtypes │ ├── README.md │ ├── run.sh │ └── src │ └── removed │ └── RemovedTypes.java ├── chapter8 ├── jackson-classpath │ ├── README.md │ ├── lib │ │ ├── jackson-annotations-2.8.8.jar │ │ ├── jackson-core-2.8.8.jar │ │ └── jackson-databind-2.8.8.jar │ ├── run.sh │ └── src │ │ └── demo │ │ ├── Book.java │ │ └── Main.java ├── jackson │ ├── README.md │ ├── lib │ │ ├── jackson-annotations-2.8.8.jar │ │ └── jackson-core-2.8.8.jar │ ├── mods │ │ └── jackson-databind-2.8.8.jar │ ├── run.sh │ └── src │ │ └── books │ │ ├── demo │ │ ├── Book.java │ │ └── Main.java │ │ └── module-info.java ├── readability_rules │ ├── README.md │ ├── jars │ │ ├── jackson-annotations-2.8.8.jar │ │ └── jackson-core-2.8.8.jar │ ├── mods │ │ └── jackson-databind-2.8.8.1.jar │ ├── run.sh │ └── src │ │ └── books │ │ ├── demo │ │ ├── Book.java │ │ └── Main.java │ │ └── module-info.java └── runtime_loading │ ├── README.md │ ├── mods │ └── hsqldb.jar │ ├── run.sh │ └── src │ └── runtime.loading.example │ ├── demo │ └── Main.java │ └── module-info.java ├── chapter9 ├── spring-hibernate-refactored │ ├── .gitignore │ ├── README.md │ ├── lib │ │ ├── antlr-2.7.7.jar │ │ ├── cdi-api-1.1.jar │ │ ├── classmate-1.3.0.jar │ │ ├── commons-dbcp-1.4.jar │ │ ├── commons-logging-1.2.jar │ │ ├── commons-pool-1.5.4.jar │ │ ├── dom4j-1.6.1.jar │ │ ├── el-api-2.2.jar │ │ ├── geronimo-jta_1.1_spec-1.1.1.jar │ │ ├── hibernate-commons-annotations-5.0.1.Final.jar │ │ ├── hsqldb-2.3.4.jar │ │ ├── jandex-2.0.0.Final.jar │ │ ├── jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar │ │ ├── jboss-logging-3.3.0.Final.jar │ │ ├── jcl-over-slf4j-1.7.21.jar │ │ ├── jsr250-api-1.0.jar │ │ ├── log4j-api-2.6.2.jar │ │ ├── log4j-core-2.6.2.jar │ │ ├── slf4j-api-1.7.21.jar │ │ ├── slf4j-simple-1.7.21.jar │ │ ├── spring-aop-4.3.2.RELEASE.jar │ │ ├── spring-beans-4.3.2.RELEASE.jar │ │ ├── spring-core-4.3.2.RELEASE.jar │ │ ├── spring-expression-4.3.2.RELEASE.jar │ │ ├── spring-jdbc-4.3.2.RELEASE.jar │ │ └── spring-orm-4.3.2.RELEASE.jar │ ├── mods │ │ ├── books.api@1.0.jar │ │ ├── books.impl@1.0.jar │ │ ├── bookstore@1.0.jar │ │ ├── hibernate-core-5.2.2.Final.jar │ │ ├── hibernate-jpa-2.1-api-1.0.0.Final.jar │ │ ├── javassist-3.20.0-GA.jar │ │ ├── javax.inject-1.jar │ │ ├── main@1.0.jar │ │ ├── spring-context-4.3.2.RELEASE.jar │ │ └── spring-tx-4.3.2.RELEASE.jar │ ├── run.sh │ └── src │ │ ├── books.api │ │ ├── books │ │ │ └── api │ │ │ │ ├── entities │ │ │ │ └── Book.java │ │ │ │ └── service │ │ │ │ └── BooksService.java │ │ └── module-info.java │ │ ├── books.impl │ │ ├── books-spring.xml │ │ ├── books │ │ │ └── impl │ │ │ │ ├── entities │ │ │ │ └── BookEntity.java │ │ │ │ └── service │ │ │ │ └── HibernateBooksService.java │ │ └── module-info.java │ │ ├── bookstore │ │ ├── bookstore-spring.xml │ │ ├── bookstore │ │ │ ├── api │ │ │ │ └── service │ │ │ │ │ └── BookstoreService.java │ │ │ └── impl │ │ │ │ └── service │ │ │ │ └── BookstoreServiceImpl.java │ │ └── module-info.java │ │ └── main │ │ ├── log4j2.xml │ │ ├── main │ │ └── Main.java │ │ └── module-info.java ├── spring-hibernate-starter │ ├── README.md │ ├── lib │ │ ├── antlr-2.7.7.jar │ │ ├── cdi-api-1.1.jar │ │ ├── classmate-1.3.0.jar │ │ ├── commons-dbcp-1.4.jar │ │ ├── commons-logging-1.2.jar │ │ ├── commons-pool-1.5.4.jar │ │ ├── dom4j-1.6.1.jar │ │ ├── el-api-2.2.jar │ │ ├── geronimo-jta_1.1_spec-1.1.1.jar │ │ ├── hibernate-commons-annotations-5.0.1.Final.jar │ │ ├── hibernate-core-5.2.2.Final.jar │ │ ├── hibernate-jpa-2.1-api-1.0.0.Final.jar │ │ ├── hsqldb-2.3.4.jar │ │ ├── jandex-2.0.0.Final.jar │ │ ├── javassist-3.20.0-GA.jar │ │ ├── javax.inject-1.jar │ │ ├── jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar │ │ ├── jboss-logging-3.3.0.Final.jar │ │ ├── jcl-over-slf4j-1.7.21.jar │ │ ├── jsr250-api-1.0.jar │ │ ├── log4j-api-2.6.2.jar │ │ ├── log4j-core-2.6.2.jar │ │ ├── slf4j-api-1.7.21.jar │ │ ├── slf4j-simple-1.7.21.jar │ │ ├── spring-aop-4.3.2.RELEASE.jar │ │ ├── spring-beans-4.3.2.RELEASE.jar │ │ ├── spring-context-4.3.2.RELEASE.jar │ │ ├── spring-core-4.3.2.RELEASE.jar │ │ ├── spring-expression-4.3.2.RELEASE.jar │ │ ├── spring-jdbc-4.3.2.RELEASE.jar │ │ ├── spring-orm-4.3.2.RELEASE.jar │ │ └── spring-tx-4.3.2.RELEASE.jar │ ├── run.sh │ └── src │ │ ├── books │ │ ├── api │ │ │ ├── entities │ │ │ │ └── Book.java │ │ │ └── service │ │ │ │ └── BooksService.java │ │ └── impl │ │ │ ├── entities │ │ │ └── BookEntity.java │ │ │ └── service │ │ │ └── HibernateBooksService.java │ │ ├── bookstore │ │ ├── api │ │ │ └── service │ │ │ │ └── BookstoreService.java │ │ └── impl │ │ │ └── service │ │ │ └── BookstoreServiceImpl.java │ │ ├── log4j2.xml │ │ ├── main.xml │ │ └── main │ │ └── Main.java └── spring-hibernate │ ├── README.md │ ├── lib │ ├── antlr-2.7.7.jar │ ├── cdi-api-1.1.jar │ ├── classmate-1.3.0.jar │ ├── commons-dbcp-1.4.jar │ ├── commons-logging-1.2.jar │ ├── commons-pool-1.5.4.jar │ ├── dom4j-1.6.1.jar │ ├── el-api-2.2.jar │ ├── geronimo-jta_1.1_spec-1.1.1.jar │ ├── hibernate-commons-annotations-5.0.1.Final.jar │ ├── hsqldb-2.3.4.jar │ ├── jandex-2.0.0.Final.jar │ ├── jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar │ ├── jboss-logging-3.3.0.Final.jar │ ├── jcl-over-slf4j-1.7.21.jar │ ├── jsr250-api-1.0.jar │ ├── log4j-api-2.6.2.jar │ ├── log4j-core-2.6.2.jar │ ├── slf4j-api-1.7.21.jar │ ├── slf4j-simple-1.7.21.jar │ ├── spring-aop-4.3.2.RELEASE.jar │ ├── spring-beans-4.3.2.RELEASE.jar │ ├── spring-core-4.3.2.RELEASE.jar │ ├── spring-expression-4.3.2.RELEASE.jar │ ├── spring-jdbc-4.3.2.RELEASE.jar │ └── spring-orm-4.3.2.RELEASE.jar │ ├── mods │ ├── hibernate-core-5.2.2.Final.jar │ ├── hibernate-jpa-2.1-api-1.0.0.Final.jar │ ├── javassist-3.20.0-GA.jar │ ├── javax.inject-1.jar │ ├── spring-context-4.3.2.RELEASE.jar │ └── spring-tx-4.3.2.RELEASE.jar │ ├── run.sh │ └── src │ └── bookapp │ ├── books │ ├── api │ │ ├── entities │ │ │ └── Book.java │ │ └── service │ │ │ └── BooksService.java │ └── impl │ │ ├── entities │ │ └── BookEntity.java │ │ └── service │ │ └── HibernateBooksService.java │ ├── bookstore │ ├── api │ │ └── service │ │ │ └── BookstoreService.java │ └── impl │ │ └── service │ │ └── BookstoreServiceImpl.java │ ├── log4j2.xml │ ├── main.xml │ ├── main │ └── Main.java │ └── module-info.java └── java9modularity-flat-cover.png /.gitignore: -------------------------------------------------------------------------------- 1 | out*/ 2 | *.class -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Java 9 Modularity cover](java9modularity-flat-cover.png) 2 | 3 | This repository contains all the example code from the [Java 9 Modularity book](http://shop.oreilly.com/product/0636920049494.do). 4 | The examples are grouped by chapter in the book: 5 | 6 | 2. Modules and Modular JDK 7 | 3. Working with Modules 8 | 4. Services 9 | 5. Modularity Patterns 10 | 6. Advanced Modularity Patterns 11 | 7. Migration Without Modules 12 | 8. Migration to Modules 13 | 9. Migration Case Study: Spring and Hibernate 14 | 10. Library Migration 15 | 11. Build Tools and IDEs 16 | 12. Testing Modules 17 | 18 | Most examples contain a `run.sh` file to compile and run the example. 19 | The scripts are tested on Mac OS and Linux. Windows users can use the Linux Subsystem for Windows, or use Cygwin to run the scripts. 20 | Some examples demonstrate errors, which means that compiling or running them may fail on purpose. 21 | A README is available in each example directory to explain the example. 22 | -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptor/README.md: -------------------------------------------------------------------------------- 1 | This example shows the usage of jdeps to generate a module descriptor. -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptor/addmoduledescriptor.sh: -------------------------------------------------------------------------------- 1 | ./build.sh 2 | cd out 3 | mkdir mylibrary-classes 4 | cd mylibrary-classes 5 | $JAVA_HOME/bin/jar -xf ../mylibrary.jar 6 | cd .. 7 | $JAVA_HOME/bin/javac -d mylibrary-classes mylibrary/module-info.java 8 | $JAVA_HOME/bin/jar -uf mylibrary.jar -C mylibrary-classes module-info.class 9 | cd .. 10 | -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptor/build.sh: -------------------------------------------------------------------------------- 1 | rm -rf out 2 | $JAVA_HOME/bin/javac -d out src/com/javamodularity/mylibrary/internal/Util.java src/com/javamodularity/mylibrary/MyLibrary.java 3 | 4 | $JAVA_HOME/bin/jar -cf out/mylibrary.jar -C out/ . 5 | 6 | $JAVA_HOME/bin/jdeps --generate-module-info ./out out/mylibrary.jar 7 | cat out/mylibrary/module-info.java 8 | -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptor/src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Module-Name: com.javamodularity.modulename 2 | -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptor/src/com/javamodularity/mylibrary/MyLibrary.java: -------------------------------------------------------------------------------- 1 | package com.javamodularity.mylibrary; 2 | 3 | import com.javamodularity.mylibrary.internal.Util; 4 | 5 | import java.sql.SQLException; 6 | import java.sql.Driver; 7 | import java.util.logging.Logger; 8 | 9 | public class MyLibrary { 10 | 11 | private Util util = new Util(); 12 | private Driver driver; 13 | 14 | public MyLibrary(Driver driver) throws SQLException { 15 | Logger logger = driver.getParentLogger(); 16 | logger.info("Started MyLibrary"); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptor/src/com/javamodularity/mylibrary/internal/Util.java: -------------------------------------------------------------------------------- 1 | package com.javamodularity.mylibrary.internal; 2 | 3 | public class Util { 4 | 5 | 6 | } 7 | -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptors_jackson/README.md: -------------------------------------------------------------------------------- 1 | This example shows using jdeps to generate module descriptors for a set of libraries. -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptors_jackson/generate.sh: -------------------------------------------------------------------------------- 1 | $JAVA_HOME/bin/jdeps --generate-module-info ./out *.jar 2 | -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptors_jackson/jackson-annotations-2.8.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter10/generate_moduledescriptors_jackson/jackson-annotations-2.8.7.jar -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptors_jackson/jackson-core-2.8.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter10/generate_moduledescriptors_jackson/jackson-core-2.8.7.jar -------------------------------------------------------------------------------- /chapter10/generate_moduledescriptors_jackson/jackson-databind-2.8.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter10/generate_moduledescriptors_jackson/jackson-databind-2.8.7.jar -------------------------------------------------------------------------------- /chapter10/modulename/README.md: -------------------------------------------------------------------------------- 1 | This example shows naming an automatic module using the `Automatic-Module-Name` manifest entry. -------------------------------------------------------------------------------- /chapter10/modulename/run.sh: -------------------------------------------------------------------------------- 1 | rm -rf out 2 | $JAVA_HOME/bin/javac -d out src/modulename/Main.java 3 | 4 | $JAVA_HOME/bin/jar -cfem out/modulename.jar modulename.Main src/META-INF/MANIFEST.MF -C out/ . 5 | 6 | # start modulename.jar as automatic module 7 | $JAVA_HOME/bin/java -ea --module-path out/modulename.jar -m com.javamodularity.modulename 8 | -------------------------------------------------------------------------------- /chapter10/modulename/src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Automatic-Module-Name: com.javamodularity.modulename 2 | -------------------------------------------------------------------------------- /chapter10/modulename/src/modulename/Main.java: -------------------------------------------------------------------------------- 1 | package modulename; 2 | 3 | public class Main { 4 | 5 | public static void main(String... args) { 6 | // TODO: Module-Name not implemented yet! 7 | String moduleName = Main.class.getModule().getName(); 8 | System.out.println("Automatic module loaded with name: " + moduleName); 9 | assert moduleName.equals("com.javamodularity.modulename"); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /chapter10/multirelease/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the multirelease feature. The META-INF/versions directory contains version specific code. 2 | The run.sh file demonstrates the commands to create the different releases. -------------------------------------------------------------------------------- /chapter10/multirelease/run.sh: -------------------------------------------------------------------------------- 1 | rm -rf out 2 | $JAVA_HOME/bin/javac --release 7 -d out/7 src/mrlib/Main.java src/mrlib/Helper.java 3 | $JAVA_HOME/bin/javac --release 9 -d out/9 src/META-INF/versions/9/mrlib/Helper.java 4 | 5 | $JAVA_HOME/bin/jar -cfem out/mrlib.jar mrlib.Main src/META-INF/MANIFEST.MF -C out/7 . 6 | $JAVA_HOME/bin/jar -uf out/mrlib.jar --release 9 -C out/9 . 7 | $JAVA_HOME/bin/java -jar out/mrlib.jar 8 | -------------------------------------------------------------------------------- /chapter10/multirelease/src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Multi-Release: true 2 | -------------------------------------------------------------------------------- /chapter10/multirelease/src/META-INF/versions/9/mrlib/Helper.java: -------------------------------------------------------------------------------- 1 | package mrlib; 2 | 3 | public class Helper { 4 | public Helper() { 5 | ModuleLayer.boot().modules().forEach(System.out::println); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /chapter10/multirelease/src/mrlib/Helper.java: -------------------------------------------------------------------------------- 1 | package mrlib; 2 | 3 | public class Helper { 4 | 5 | public Helper() { 6 | System.out.println("Not using any Java 9 APIs"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /chapter10/multirelease/src/mrlib/Main.java: -------------------------------------------------------------------------------- 1 | package mrlib; 2 | 3 | public class Main { 4 | public static void main(String... args) { 5 | new Helper(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /chapter11/multi-module/README.md: -------------------------------------------------------------------------------- 1 | This example is the EasyText application as a multi module Maven project. 2 | It also demonstrates using the Maven exec plugin to run a modular application (see cli/pom.xml). -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | easytext 7 | parent 8 | 1.0-SNAPSHOT 9 | 10 | 11 | algorithm.api 12 | 13 | Algorithm API 14 | 15 | -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.api/src/main/java/javamodularity/easytext/algorithm/api/Analyzer.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.algorithm.api; 2 | 3 | import java.util.List; 4 | 5 | public interface Analyzer { 6 | 7 | String getName(); 8 | 9 | double analyze(List> text); 10 | 11 | } -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.api/src/main/java/javamodularity/easytext/algorithm/api/Preprocessing.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.algorithm.api; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Preprocessing { 7 | 8 | public static List> toSentences(String text) { 9 | String removedBreaks = text.replaceAll("\\r?\\n", " "); 10 | ArrayList> sentences = new ArrayList<>(); 11 | for(String rawSentence: removedBreaks.split("[\\.\\?\\!]")) { 12 | List words = toWords(rawSentence); 13 | if(words.size() > 0) { 14 | sentences.add(words); 15 | } 16 | } 17 | 18 | return sentences; 19 | } 20 | 21 | public static List toWords(String sentence) { 22 | String[] rawWords = sentence.split("\\s+"); 23 | List words = new ArrayList<>(); 24 | for(String rawWord: rawWords) { 25 | String word = rawWord.replaceAll("\\W", ""); 26 | if(word.length() > 0) { 27 | words.add(word); 28 | } 29 | } 30 | 31 | return words; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.api/src/main/java/javamodularity/easytext/algorithm/api/SyllableCounter.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.algorithm.api; 2 | 3 | public interface SyllableCounter { 4 | int countSyllables(String word); 5 | } -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.api/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.algorithm.api { 2 | 3 | exports javamodularity.easytext.algorithm.api; 4 | 5 | } 6 | -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.coleman/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | easytext 7 | parent 8 | 1.0-SNAPSHOT 9 | 10 | 11 | algorithm.coleman 12 | 13 | Coleman algorithm 14 | 15 | 16 | 17 | easytext 18 | algorithm.api 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.coleman/src/main/java/javamodularity/easytext/algorithm/coleman/ColemanAnalyzer.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.algorithm.coleman; 2 | 3 | import java.util.List; 4 | 5 | import javamodularity.easytext.algorithm.api.Analyzer; 6 | 7 | public class ColemanAnalyzer implements Analyzer { 8 | 9 | public String getName() { 10 | return "Coleman-Liau"; 11 | } 12 | 13 | public double analyze(List> sentences) { 14 | float totalsentences = sentences.size(); 15 | float words = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 16 | float letters = sentences.stream().flatMapToInt(sentence -> sentence.stream().mapToInt(word -> word.length())).sum(); 17 | 18 | return 0.0588 * (letters / (words / 100)) - 0.296 * (totalsentences / (words / 100)) - 15.8; 19 | } 20 | } -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.coleman/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.algorithm.coleman { 2 | 3 | requires easytext.algorithm.api; 4 | 5 | provides javamodularity.easytext.algorithm.api.Analyzer 6 | with javamodularity.easytext.algorithm.coleman.ColemanAnalyzer; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.kincaid/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | easytext 5 | algorithm.kincaid 6 | jar 7 | 1.0-SNAPSHOT 8 | algorithm.kincaid 9 | 10 | 11 | easytext 12 | parent 13 | 1.0-SNAPSHOT 14 | 15 | 16 | 17 | 18 | easytext 19 | algorithm.api 20 | ${project.version} 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.kincaid/src/main/java/javamodularity/easytext/algorithm/kincaid/KincaidAnalyzer.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.algorithm.kincaid; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | import java.util.ServiceLoader; 6 | 7 | import javamodularity.easytext.algorithm.api.Analyzer; 8 | import javamodularity.easytext.algorithm.api.SyllableCounter; 9 | 10 | public class KincaidAnalyzer implements Analyzer { 11 | 12 | private SyllableCounter syllableCounter; 13 | 14 | public KincaidAnalyzer() { 15 | Iterator counters = ServiceLoader.load(SyllableCounter.class).iterator(); 16 | if(counters.hasNext()) { 17 | this.syllableCounter = counters.next(); 18 | } else { 19 | throw new IllegalStateException("SyllableCounter not found"); 20 | } 21 | } 22 | 23 | public String getName() { 24 | return "Flesch-Kincaid"; 25 | } 26 | 27 | public double analyze(List> sentences) { 28 | float totalsentences = sentences.size(); 29 | float totalwords = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 30 | float totalsyllables = sentences.stream() 31 | .flatMapToInt(sentence -> 32 | sentence.stream().mapToInt(word -> syllableCounter.countSyllables(word))) 33 | .sum(); 34 | return 206.835 - 1.015 * (totalwords / totalsentences) - 84.6 * (totalsyllables / totalwords); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.kincaid/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.algorithm.kincaid { 2 | 3 | requires easytext.algorithm.api; 4 | 5 | provides javamodularity.easytext.algorithm.api.Analyzer 6 | with javamodularity.easytext.algorithm.kincaid.KincaidAnalyzer; 7 | 8 | uses javamodularity.easytext.algorithm.api.SyllableCounter; 9 | } 10 | -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.naivesyllablecounter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | easytext 7 | parent 8 | 1.0-SNAPSHOT 9 | 10 | 11 | algorithm.naivesyllablecounter 12 | 13 | Syllables in Naive algorithm 14 | 15 | 16 | 17 | easytext 18 | algorithm.api 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.naivesyllablecounter/src/main/java/javamodularity/easytext/algorithm/naivesyllablecounter/NaiveSyllableCounter.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.algorithm.naivesyllablecounter; 2 | 3 | import javamodularity.easytext.algorithm.api.SyllableCounter; 4 | 5 | public class NaiveSyllableCounter implements SyllableCounter { 6 | 7 | @Override 8 | public int countSyllables(String word) { 9 | int syllables = 0; 10 | boolean prevNonVowel = false; 11 | for(int i = 0; i < word.length(); i++) { 12 | boolean isVowel = isVowel(word.toLowerCase().charAt(i)); 13 | if(prevNonVowel && isVowel && i != word.length() - 1) { 14 | syllables++; 15 | } 16 | prevNonVowel = !isVowel; 17 | } 18 | syllables = syllables == 0 ? 1 : syllables; 19 | return syllables; 20 | } 21 | 22 | private boolean isVowel(char letter) { 23 | return letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u'; 24 | } 25 | } -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.naivesyllablecounter/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.algorithm.naivesyllablecounter { 2 | requires easytext.algorithm.api; 3 | 4 | provides javamodularity.easytext.algorithm.api.SyllableCounter 5 | with javamodularity.easytext.algorithm.naivesyllablecounter.NaiveSyllableCounter; 6 | } 7 | -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.nextgensyllablecounter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | easytext 7 | parent 8 | 1.0-SNAPSHOT 9 | 10 | 11 | algorithm.nextgensyllablecounter 12 | 13 | Syllable NextGen algorithm 14 | 15 | 16 | 17 | easytext 18 | algorithm.api 19 | 20 | 21 | 22 | eu.crydee 23 | syllable-counter 24 | 3.0.1 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.nextgensyllablecounter/src/main/java/javamodularity/easytext/algorithm/nextgensyllablecounter/SyllableCounter3Wrapper.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.algorithm.nextgensyllablecounter; 2 | 3 | import javamodularity.easytext.algorithm.api.SyllableCounter; 4 | 5 | public class SyllableCounter3Wrapper implements SyllableCounter { 6 | 7 | eu.crydee.syllablecounter.SyllableCounter counter = new 8 | eu.crydee.syllablecounter.SyllableCounter(1000); 9 | 10 | @Override 11 | public int countSyllables(String word) { 12 | return counter.count(word); 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /chapter11/multi-module/algorithm.nextgensyllablecounter/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.algorithm.nextgensyllablecounter { 2 | requires easytext.algorithm.api; 3 | requires syllable.counter; // Automatic module: name derived from library jar name 4 | 5 | provides javamodularity.easytext.algorithm.api.SyllableCounter 6 | with javamodularity.easytext.algorithm.nextgensyllablecounter.SyllableCounter3Wrapper; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /chapter11/multi-module/cli/README.adoc: -------------------------------------------------------------------------------- 1 | README 2 | ====== 3 | 4 | You can run this application like this 5 | 6 | mvn exec:exec -Deasytext.file=/path/to/some/file.adoc 7 | 8 | When `easytext.file` is not specified, this `README.adoc` file is used to analyze. -------------------------------------------------------------------------------- /chapter11/multi-module/cli/src/main/java/javamodularity/easytext/cli/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.cli; 2 | 3 | import java.io.IOException; 4 | import java.nio.charset.Charset; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.ServiceLoader; 11 | 12 | import javamodularity.easytext.algorithm.api.Analyzer; 13 | import static javamodularity.easytext.algorithm.api.Preprocessing.toSentences; 14 | 15 | public class Main { 16 | 17 | public static void main(String... args) throws IOException { 18 | if (args.length == 0) { 19 | System.out.println("Welcome to EasyText. Please provide a filename as input argument"); 20 | return; 21 | } 22 | 23 | Path path = Paths.get(args[0]); 24 | System.out.println("Reading " + path); 25 | String text = new String(Files.readAllBytes(path), Charset.forName("UTF-8")); 26 | 27 | List> sentences = toSentences(text); 28 | 29 | Iterable analyzers = ServiceLoader.load(Analyzer.class); 30 | for(Analyzer analyzer: analyzers) { 31 | System.out.println(analyzer.getName() + ": " + analyzer.analyze(sentences)); 32 | } 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /chapter11/multi-module/cli/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.cli { 2 | requires easytext.algorithm.api; 3 | 4 | uses javamodularity.easytext.algorithm.api.Analyzer; 5 | } 6 | -------------------------------------------------------------------------------- /chapter11/multi-module/cli/src/main/resources/test.txt: -------------------------------------------------------------------------------- 1 | this is a test -------------------------------------------------------------------------------- /chapter11/multi-module/gui/gui.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /chapter11/multi-module/gui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | easytext 7 | parent 8 | 1.0-SNAPSHOT 9 | 10 | 11 | gui 12 | 13 | GUI 14 | 15 | 16 | 17 | easytext 18 | algorithm.api 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /chapter11/multi-module/gui/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.gui { 2 | // JavaFX needs to instantiate our Main Application class 3 | exports javamodularity.easytext.gui to javafx.graphics; 4 | 5 | requires javafx.graphics; 6 | requires javafx.controls; 7 | requires easytext.algorithm.api; 8 | 9 | uses javamodularity.easytext.algorithm.api.Analyzer; 10 | } 11 | -------------------------------------------------------------------------------- /chapter11/multi-module/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | easytext 6 | parent 7 | 1.0-SNAPSHOT 8 | pom 9 | 10 | EasyText parent 11 | 12 | 13 | algorithm.api 14 | algorithm.coleman 15 | algorithm.kincaid 16 | algorithm.naivesyllablecounter 17 | algorithm.nextgensyllablecounter 18 | gui 19 | cli 20 | 21 | 22 | 23 | UTF-8 24 | 25 | 26 | 27 | 28 | 29 | easytext 30 | algorithm.api 31 | ${project.version} 32 | 33 | 34 | easytext 35 | algorithm.coleman 36 | ${project.version} 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | org.apache.maven.plugins 46 | maven-compiler-plugin 47 | 3.6.1 48 | 49 | 9 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /chapter11/multi-module/run.sh: -------------------------------------------------------------------------------- 1 | mvn install 2 | cd cli 3 | mvn exec:exec -------------------------------------------------------------------------------- /chapter11/single-module/README.md: -------------------------------------------------------------------------------- 1 | This example is a minimal single module Maven setup. -------------------------------------------------------------------------------- /chapter11/single-module/my-app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /chapter11/single-module/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | javamodularity.toolexamples 5 | single-module-example 6 | jar 7 | 1.0-SNAPSHOT 8 | Single Module Example 9 | 10 | 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 3.6.1 16 | 17 | 9 18 | 9 19 | 20 | 21 | 22 | 23 | org.codehaus.mojo 24 | exec-maven-plugin 25 | 1.6.0 26 | 27 | 28 | 29 | exec 30 | 31 | 32 | 33 | 34 | ${JAVA_HOME}/bin/java 35 | 36 | --module-path 37 | 38 | --module 39 | books/javamodularity.maven.example.Main 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | com.fasterxml.jackson.core 50 | jackson-databind 51 | 2.8.8 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /chapter11/single-module/run.sh: -------------------------------------------------------------------------------- 1 | mvn install exec:exec -------------------------------------------------------------------------------- /chapter11/single-module/src/main/java/javamodularity/maven/example/Book.java: -------------------------------------------------------------------------------- 1 | package javamodularity.maven.example; 2 | 3 | public class Book { 4 | private String title; 5 | private String description; 6 | 7 | public Book(String title, String description) { 8 | this.title = title; 9 | this.description = description; 10 | } 11 | 12 | public String getTitle() { 13 | return title; 14 | } 15 | 16 | public String getDescription() { 17 | return description; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chapter11/single-module/src/main/java/javamodularity/maven/example/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.maven.example; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | public class Main { 6 | 7 | public static void main(String... args) throws Exception { 8 | Book modularityBook = 9 | new Book("Java 9 Modularity", "Modularize all the things!"); 10 | 11 | ObjectMapper mapper = new ObjectMapper(); 12 | String json = mapper.writeValueAsString(modularityBook); 13 | System.out.println(json); 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter11/single-module/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module books { 2 | requires jackson.databind; 3 | opens javamodularity.maven.example; 4 | } 5 | -------------------------------------------------------------------------------- /chapter12/blackbox/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates testing modules from the outside (blackbox testing). The tests live in their own module. -------------------------------------------------------------------------------- /chapter12/blackbox/lib/hamcrest-core-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter12/blackbox/lib/hamcrest-core-1.3.jar -------------------------------------------------------------------------------- /chapter12/blackbox/lib/junit-4.12.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter12/blackbox/lib/junit-4.12.jar -------------------------------------------------------------------------------- /chapter12/blackbox/run.test.junit.sh: -------------------------------------------------------------------------------- 1 | rm -rf out*/ 2 | $JAVA_HOME/bin/javac --module-source-path src -d out -m easytext.syllablecounter 3 | $JAVA_HOME/bin/javac --module-path lib:out --module-source-path src-test -d out-test -m easytext.syllablecounter.junit 4 | $JAVA_HOME/bin/java --module-path lib:out:out-test \ 5 | --add-modules easytext.syllablecounter.junit \ 6 | -m junit/org.junit.runner.JUnitCore javamodularity.easytext.test.JUnitTestSyllableCounter 7 | -------------------------------------------------------------------------------- /chapter12/blackbox/run.test.sh: -------------------------------------------------------------------------------- 1 | rm -rf out*/ 2 | $JAVA_HOME/bin/javac --module-source-path src -d out -m easytext.syllablecounter 3 | $JAVA_HOME/bin/javac --module-path out --module-source-path src-test -d out-test -m easytext.syllablecounter.test 4 | $JAVA_HOME/bin/java -ea --module-path out:out-test \ 5 | -m easytext.syllablecounter.test/javamodularity.easytext.test.TestSyllableCounter 6 | -------------------------------------------------------------------------------- /chapter12/blackbox/src-test/easytext.syllablecounter.junit/javamodularity/easytext/test/JUnitTestSyllableCounter.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.test; 2 | 3 | import org.junit.Test; 4 | import javamodularity.easytext.syllablecounter.SimpleSyllableCounter; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | public class JUnitTestSyllableCounter { 9 | 10 | private SimpleSyllableCounter counter = new SimpleSyllableCounter(); 11 | 12 | @Test 13 | public void testSyllableCounter() { 14 | assertEquals(1, counter.countSyllables("Bike")); 15 | assertEquals(2, counter.countSyllables("Motor")); 16 | assertEquals(3, counter.countSyllables("Bicycle")); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter12/blackbox/src-test/easytext.syllablecounter.junit/module-info.java: -------------------------------------------------------------------------------- 1 | open module easytext.syllablecounter.junit { 2 | requires easytext.syllablecounter; 3 | requires junit; 4 | } 5 | -------------------------------------------------------------------------------- /chapter12/blackbox/src-test/easytext.syllablecounter.test/javamodularity/easytext/test/TestSyllableCounter.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.test; 2 | 3 | import javamodularity.easytext.syllablecounter.SimpleSyllableCounter; 4 | 5 | public class TestSyllableCounter { 6 | 7 | public static void main(String... args) { 8 | SimpleSyllableCounter sc = new SimpleSyllableCounter(); 9 | 10 | assert sc.countSyllables("Bike") == 1; 11 | assert sc.countSyllables("Motor") == 2; 12 | assert sc.countSyllables("Bicycle") == 3; 13 | 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /chapter12/blackbox/src-test/easytext.syllablecounter.test/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.syllablecounter.test { 2 | requires easytext.syllablecounter; 3 | } 4 | -------------------------------------------------------------------------------- /chapter12/blackbox/src/easytext.syllablecounter/javamodularity/easytext/syllablecounter/SimpleSyllableCounter.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.syllablecounter; 2 | 3 | import javamodularity.easytext.syllablecounter.vowel.VowelHelper; 4 | 5 | public class SimpleSyllableCounter { 6 | 7 | public int countSyllables(String word) { 8 | int syllables = 0; 9 | boolean prevNonVowel = false; 10 | for(int i = 0; i < word.length(); i++) { 11 | boolean isVowel = VowelHelper.isVowel(word.toLowerCase().charAt(i)); 12 | if(prevNonVowel && isVowel && i != word.length() - 1) { 13 | syllables++; 14 | } 15 | prevNonVowel = !isVowel; 16 | } 17 | syllables = syllables == 0 ? 1 : syllables; 18 | return syllables; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /chapter12/blackbox/src/easytext.syllablecounter/javamodularity/easytext/syllablecounter/vowel/VowelHelper.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.syllablecounter.vowel; 2 | 3 | import java.util.Set; 4 | 5 | public class VowelHelper { 6 | 7 | public static boolean isVowel(char letter) { 8 | return getVowels().contains(letter); 9 | } 10 | 11 | static Set getVowels() { 12 | return Set.of('a', 'e', 'i', 'o', 'u'); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /chapter12/blackbox/src/easytext.syllablecounter/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.syllablecounter { 2 | exports javamodularity.easytext.syllablecounter; 3 | } 4 | -------------------------------------------------------------------------------- /chapter12/whitebox/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates testing code in a module without respecting the module boundaries (whitebox testing). 2 | There's both an example of whitebox testing by using the classpath, and an example that uses the module-path with extra flags to break encapsulation. -------------------------------------------------------------------------------- /chapter12/whitebox/lib/hamcrest-core-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter12/whitebox/lib/hamcrest-core-1.3.jar -------------------------------------------------------------------------------- /chapter12/whitebox/lib/junit-4.12.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter12/whitebox/lib/junit-4.12.jar -------------------------------------------------------------------------------- /chapter12/whitebox/run.test.junit.classpath.sh: -------------------------------------------------------------------------------- 1 | rm -rf out*/ 2 | $JAVA_HOME/bin/javac --module-source-path src -d out -m easytext.syllablecounter 3 | $JAVA_HOME/bin/javac -cp lib/junit-4.12.jar:out/easytext.syllablecounter -d out-test \ 4 | src-test/javamodularity/easytext/syllablecounter/vowel/JUnitTestVowelHelper.java 5 | 6 | $JAVA_HOME/bin/java -cp lib/junit-4.12.jar:lib/hamcrest-core-1.3.jar:out/easytext.syllablecounter:out-test \ 7 | org.junit.runner.JUnitCore javamodularity.easytext.syllablecounter.vowel.JUnitTestVowelHelper 8 | -------------------------------------------------------------------------------- /chapter12/whitebox/run.test.junit.modulepath.sh: -------------------------------------------------------------------------------- 1 | rm -rf out*/ 2 | $JAVA_HOME/bin/javac --module-source-path src -d out -m easytext.syllablecounter 3 | $JAVA_HOME/bin/javac --patch-module easytext.syllablecounter=src-test \ 4 | --module-path lib:out \ 5 | --add-modules junit \ 6 | --add-reads easytext.syllablecounter=junit \ 7 | -d out-test src-test/javamodularity/easytext/syllablecounter/vowel/JUnitTestVowelHelper.java 8 | $JAVA_HOME/bin/java --patch-module easytext.syllablecounter=out-test \ 9 | --add-reads easytext.syllablecounter=junit \ 10 | --add-opens easytext.syllablecounter/javamodularity.easytext.syllablecounter.vowel=junit \ 11 | --module-path lib:out \ 12 | --add-modules easytext.syllablecounter \ 13 | -m junit/org.junit.runner.JUnitCore javamodularity.easytext.syllablecounter.vowel.JUnitTestVowelHelper 14 | -------------------------------------------------------------------------------- /chapter12/whitebox/src-test/javamodularity/easytext/syllablecounter/vowel/JUnitTestVowelHelper.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.syllablecounter.vowel; 2 | 3 | import org.junit.Test; 4 | import javamodularity.easytext.syllablecounter.vowel.VowelHelper; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | import static org.junit.Assert.assertTrue; 8 | 9 | public class JUnitTestVowelHelper { 10 | 11 | @Test 12 | public void testIsVowel() { 13 | assertTrue(VowelHelper.isVowel('e')); 14 | } 15 | 16 | @Test 17 | public void testGetVowels() { 18 | assertEquals(5, VowelHelper.getVowels().size()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /chapter12/whitebox/src/easytext.syllablecounter/javamodularity/easytext/syllablecounter/SimpleSyllableCounter.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.syllablecounter; 2 | 3 | import javamodularity.easytext.syllablecounter.vowel.VowelHelper; 4 | 5 | public class SimpleSyllableCounter { 6 | 7 | public int countSyllables(String word) { 8 | int syllables = 0; 9 | boolean prevNonVowel = false; 10 | for(int i = 0; i < word.length(); i++) { 11 | boolean isVowel = VowelHelper.isVowel(word.toLowerCase().charAt(i)); 12 | if(prevNonVowel && isVowel && i != word.length() - 1) { 13 | syllables++; 14 | } 15 | prevNonVowel = !isVowel; 16 | } 17 | syllables = syllables == 0 ? 1 : syllables; 18 | return syllables; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /chapter12/whitebox/src/easytext.syllablecounter/javamodularity/easytext/syllablecounter/vowel/VowelHelper.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.syllablecounter.vowel; 2 | 3 | import java.util.Set; 4 | 5 | public class VowelHelper { 6 | 7 | public static boolean isVowel(char letter) { 8 | return getVowels().contains(letter); 9 | } 10 | 11 | static Set getVowels() { 12 | return Set.of('a', 'e', 'i', 'o', 'u'); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /chapter12/whitebox/src/easytext.syllablecounter/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.syllablecounter { 2 | exports javamodularity.easytext.syllablecounter; 3 | } 4 | -------------------------------------------------------------------------------- /chapter2/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates that the classpath still exists. We can build and run code without modules. -------------------------------------------------------------------------------- /chapter2/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p out 2 | 3 | $JAVA_HOME/bin/javac -d out -sourcepath src $(find src -name '*.java') 4 | $JAVA_HOME/bin/java -cp out NotInModule 5 | -------------------------------------------------------------------------------- /chapter2/src/NotInModule.java: -------------------------------------------------------------------------------- 1 | import java.util.logging.Level; 2 | import java.util.logging.Logger; 3 | import java.util.logging.LogRecord; 4 | 5 | 6 | public class NotInModule { 7 | 8 | public static void main(String... args) { 9 | Logger logger = Logger.getGlobal(); 10 | LogRecord message = 11 | new LogRecord(Level.INFO, "This still works!"); 12 | logger.log(message); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /chapter3/easytext-singlemodule/README.md: -------------------------------------------------------------------------------- 1 | This example shows EasyText as a single module. -------------------------------------------------------------------------------- /chapter3/easytext-singlemodule/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p out 2 | 3 | $JAVA_HOME/bin/javac -d out --module-source-path src -m easytext 4 | $JAVA_HOME/bin/java --module-path out -m easytext/javamodularity.easytext.Main 5 | -------------------------------------------------------------------------------- /chapter3/easytext-singlemodule/src/easytext/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /chapter3/easytext-threemodules/README.md: -------------------------------------------------------------------------------- 1 | This example shows EasyText with both a cli and gui, both using the same analysis module. -------------------------------------------------------------------------------- /chapter3/easytext-threemodules/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p out 2 | 3 | $JAVA_HOME/bin/javac -d out --module-source-path src -m easytext.cli,easytext.gui,easytext.analysis 4 | $JAVA_HOME/bin/java --module-path out -m easytext.cli/javamodularity.easytext.cli.Main 5 | -------------------------------------------------------------------------------- /chapter3/easytext-threemodules/src/easytext.analysis/javamodularity/easytext/analysis/FleschKincaid.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class FleschKincaid { 7 | 8 | public double analyze(List> sentences) { 9 | float totalsentences = sentences.size(); 10 | float totalwords = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 11 | float totalsyllables = sentences.stream() 12 | .flatMapToInt(sentence -> 13 | sentence.stream().mapToInt(word -> countSyllables(word))) 14 | .sum(); 15 | return 206.835 - 1.015 * (totalwords / totalsentences) - 84.6 * (totalsyllables / totalwords); 16 | } 17 | 18 | private int countSyllables(String word) { 19 | int syllables = 0; 20 | boolean prevNonVowel = false; 21 | for(int i = 0; i < word.length(); i++) { 22 | boolean isVowel = isVowel(word.toLowerCase().charAt(i)); 23 | if(prevNonVowel && isVowel && i != word.length() - 1) { 24 | syllables++; 25 | } 26 | prevNonVowel = !isVowel; 27 | } 28 | syllables = syllables == 0 ? 1 : syllables; 29 | return syllables; 30 | } 31 | 32 | private boolean isVowel(char letter) { 33 | return letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u'; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /chapter3/easytext-threemodules/src/easytext.analysis/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis { 2 | exports javamodularity.easytext.analysis; 3 | } 4 | -------------------------------------------------------------------------------- /chapter3/easytext-threemodules/src/easytext.cli/javamodularity/easytext/cli/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.cli; 2 | 3 | import java.io.IOException; 4 | import java.nio.charset.Charset; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import javamodularity.easytext.analysis.FleschKincaid; 12 | 13 | public class Main { 14 | 15 | public static void main(String... args) throws IOException { 16 | if (args.length == 0) { 17 | System.out.println("Welcome to EasyText. Please provide a filename as input argument"); 18 | return; 19 | } 20 | 21 | Path path = Paths.get(args[0]); 22 | System.out.println("Reading " + path); 23 | String text = new String(Files.readAllBytes(path), Charset.forName("UTF-8")); 24 | 25 | List> sentences = toSentences(text); 26 | 27 | System.out.println("Flesch-Kincaid: " + new FleschKincaid().analyze(sentences)); 28 | 29 | } 30 | 31 | 32 | public static List> toSentences(String text) { 33 | String removedBreaks = text.replaceAll("\\r?\\n", " "); 34 | ArrayList> sentences = new ArrayList<>(); 35 | for(String rawSentence: removedBreaks.split("[\\.\\?\\!]")) { 36 | List words = toWords(rawSentence); 37 | if(words.size() > 0) { 38 | sentences.add(words); 39 | } 40 | } 41 | 42 | return sentences; 43 | } 44 | 45 | public static List toWords(String sentence) { 46 | String[] rawWords = sentence.split("\\s+"); 47 | List words = new ArrayList<>(); 48 | for(String rawWord: rawWords) { 49 | String word = rawWord.replaceAll("\\W", ""); 50 | if(word.length() > 0) { 51 | words.add(word); 52 | } 53 | } 54 | 55 | return words; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /chapter3/easytext-threemodules/src/easytext.cli/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.cli { 2 | requires easytext.analysis; 3 | } 4 | -------------------------------------------------------------------------------- /chapter3/easytext-threemodules/src/easytext.gui/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.gui { 2 | 3 | exports javamodularity.easytext.gui to javafx.graphics; 4 | 5 | requires javafx.graphics; 6 | requires javafx.controls; 7 | requires easytext.analysis; 8 | } 9 | -------------------------------------------------------------------------------- /chapter3/easytext-twomodules/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates EasyText split into a cli and analysis module. -------------------------------------------------------------------------------- /chapter3/easytext-twomodules/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p out 2 | 3 | $JAVA_HOME/bin/javac -d out --module-source-path src -m easytext.cli,easytext.analysis 4 | $JAVA_HOME/bin/java --module-path out -m easytext.cli/javamodularity.easytext.cli.Main 5 | -------------------------------------------------------------------------------- /chapter3/easytext-twomodules/src/easytext.analysis/javamodularity/easytext/analysis/FleschKincaid.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class FleschKincaid { 7 | 8 | public double analyze(List> sentences) { 9 | float totalsentences = sentences.size(); 10 | float totalwords = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 11 | float totalsyllables = sentences.stream() 12 | .flatMapToInt(sentence -> 13 | sentence.stream().mapToInt(word -> countSyllables(word))) 14 | .sum(); 15 | return 206.835 - 1.015 * (totalwords / totalsentences) - 84.6 * (totalsyllables / totalwords); 16 | } 17 | 18 | private int countSyllables(String word) { 19 | int syllables = 0; 20 | boolean prevNonVowel = false; 21 | for(int i = 0; i < word.length(); i++) { 22 | boolean isVowel = isVowel(word.toLowerCase().charAt(i)); 23 | if(prevNonVowel && isVowel && i != word.length() - 1) { 24 | syllables++; 25 | } 26 | prevNonVowel = !isVowel; 27 | } 28 | syllables = syllables == 0 ? 1 : syllables; 29 | return syllables; 30 | } 31 | 32 | private boolean isVowel(char letter) { 33 | return letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u'; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /chapter3/easytext-twomodules/src/easytext.analysis/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis { 2 | exports javamodularity.easytext.analysis; 3 | } 4 | -------------------------------------------------------------------------------- /chapter3/easytext-twomodules/src/easytext.cli/javamodularity/easytext/cli/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.cli; 2 | 3 | import java.io.IOException; 4 | import java.nio.charset.Charset; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import javamodularity.easytext.analysis.FleschKincaid; 12 | 13 | public class Main { 14 | 15 | public static void main(String... args) throws IOException { 16 | if (args.length == 0) { 17 | System.out.println("Welcome to EasyText. Please provide a filename as input argument"); 18 | return; 19 | } 20 | 21 | Path path = Paths.get(args[0]); 22 | System.out.println("Reading " + path); 23 | String text = new String(Files.readAllBytes(path), Charset.forName("UTF-8")); 24 | 25 | List> sentences = toSentences(text); 26 | 27 | System.out.println("Flesch-Kincaid: " + new FleschKincaid().analyze(sentences)); 28 | 29 | } 30 | 31 | 32 | public static List> toSentences(String text) { 33 | String removedBreaks = text.replaceAll("\\r?\\n", " "); 34 | ArrayList> sentences = new ArrayList<>(); 35 | for(String rawSentence: removedBreaks.split("[\\.\\?\\!]")) { 36 | List words = toWords(rawSentence); 37 | if(words.size() > 0) { 38 | sentences.add(words); 39 | } 40 | } 41 | 42 | return sentences; 43 | } 44 | 45 | public static List toWords(String sentence) { 46 | String[] rawWords = sentence.split("\\s+"); 47 | List words = new ArrayList<>(); 48 | for(String rawWord: rawWords) { 49 | String word = rawWord.replaceAll("\\W", ""); 50 | if(word.length() > 0) { 51 | words.add(word); 52 | } 53 | } 54 | 55 | return words; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /chapter3/easytext-twomodules/src/easytext.cli/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.cli { 2 | requires easytext.analysis; 3 | } 4 | -------------------------------------------------------------------------------- /chapter3/helloworld/README.md: -------------------------------------------------------------------------------- 1 | This is the first module example in the book. It's a single module application, that's packaged as a modular JAR file. 2 | A custom runtime image can be created using jlink (see [link.sh](link.sh)). -------------------------------------------------------------------------------- /chapter3/helloworld/link.sh: -------------------------------------------------------------------------------- 1 | $JAVA_HOME/bin/jlink --module-path mods/:$JAVA_HOME/jmods \ 2 | --add-modules helloworld \ 3 | --launcher hello=helloworld \ 4 | --output helloworld-image -------------------------------------------------------------------------------- /chapter3/helloworld/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p out 2 | mkdir -p mods 3 | 4 | $JAVA_HOME/bin/javac -d out/helloworld \ 5 | src/helloworld/com/javamodularity/helloworld/HelloWorld.java \ 6 | src/helloworld/module-info.java 7 | 8 | $JAVA_HOME/bin/jar -cfe mods/helloworld.jar com.javamodularity.helloworld.HelloWorld -C out/helloworld . 9 | 10 | $JAVA_HOME/bin/java --module-path out \ 11 | --module helloworld/com.javamodularity.helloworld.HelloWorld 12 | -------------------------------------------------------------------------------- /chapter3/helloworld/src/helloworld/com/javamodularity/helloworld/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package com.javamodularity.helloworld; 2 | 3 | public class HelloWorld { 4 | 5 | public static void main(String... args) { 6 | System.out.println("Hello Modular World!"); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /chapter3/helloworld/src/helloworld/module-info.java: -------------------------------------------------------------------------------- 1 | module helloworld { 2 | 3 | } -------------------------------------------------------------------------------- /chapter4/easytext-factory/README.md: -------------------------------------------------------------------------------- 1 | The example demonstrates implementation hiding using a factory. 2 | Note that this is not ideal, and is primarily an example for the need for services. -------------------------------------------------------------------------------- /chapter4/easytext-factory/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p out 2 | 3 | $JAVA_HOME/bin/javac -d out --module-source-path src -m easytext.cli,easytext.gui,easytext.analysis.api,easytext.analysis.coleman,easytext.analysis.factory,easytext.analysis.kincaid 4 | $JAVA_HOME/bin/java --module-path out -m easytext.cli/javamodularity.easytext.cli.Main ../exampletext.txt 5 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.analysis.api/javamodularity/easytext/analysis/api/Analyzer.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.api; 2 | 3 | import java.util.List; 4 | 5 | public interface Analyzer { 6 | 7 | String getName(); 8 | 9 | double analyze(List> text); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.analysis.api/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.api { 2 | exports javamodularity.easytext.analysis.api; 3 | } 4 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.analysis.coleman/javamodularity/easytext/analysis/coleman/Coleman.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.coleman; 2 | 3 | import javamodularity.easytext.analysis.api.Analyzer; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class Coleman implements Analyzer { 9 | 10 | public static final String NAME = "Coleman-Liau"; 11 | 12 | @Override 13 | public String getName() { 14 | return NAME; 15 | } 16 | 17 | @Override 18 | public double analyze(List> sentences) { 19 | float totalsentences = sentences.size(); 20 | float words = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 21 | float letters = sentences.stream().flatMapToInt(sentence -> sentence.stream().mapToInt(word -> word.length())).sum(); 22 | 23 | return 0.0588 * (letters / (words / 100)) - 0.296 * (totalsentences / (words / 100)) - 15.8; 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.analysis.coleman/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.coleman { 2 | requires easytext.analysis.api; 3 | 4 | exports javamodularity.easytext.analysis.coleman; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.analysis.factory/javamodularity/easytext/analysis/factory/AnalyzerFactory.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.factory; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import javamodularity.easytext.analysis.api.Analyzer; 7 | import javamodularity.easytext.analysis.kincaid.FleschKincaid; 8 | import javamodularity.easytext.analysis.coleman.Coleman; 9 | 10 | public class AnalyzerFactory { 11 | 12 | public static List getSupportedAnalyses() { 13 | return List.of(FleschKincaid.NAME, Coleman.NAME); 14 | } 15 | 16 | public static Analyzer getAnalyzer(String name) { 17 | switch (name) { 18 | case FleschKincaid.NAME: return new FleschKincaid(); 19 | case Coleman.NAME: return new Coleman(); 20 | default: throw new IllegalArgumentException("No such analyzer!"); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.analysis.factory/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.factory { 2 | requires transitive easytext.analysis.api; 3 | requires easytext.analysis.kincaid; 4 | requires easytext.analysis.coleman; 5 | 6 | exports javamodularity.easytext.analysis.factory; 7 | } 8 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.analysis.kincaid/javamodularity/easytext/analysis/kincaid/FleschKincaid.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.kincaid; 2 | 3 | import javamodularity.easytext.analysis.api.Analyzer; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class FleschKincaid implements Analyzer { 9 | 10 | public static final String NAME = "Flesch-Kincaid"; 11 | 12 | @Override 13 | public String getName() { 14 | return NAME; 15 | } 16 | 17 | @Override 18 | public double analyze(List> sentences) { 19 | float totalsentences = sentences.size(); 20 | float totalwords = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 21 | float totalsyllables = sentences.stream() 22 | .flatMapToInt(sentence -> 23 | sentence.stream().mapToInt(word -> countSyllables(word))) 24 | .sum(); 25 | return 206.835 - 1.015 * (totalwords / totalsentences) - 84.6 * (totalsyllables / totalwords); 26 | } 27 | 28 | private int countSyllables(String word) { 29 | int syllables = 0; 30 | boolean prevNonVowel = false; 31 | for(int i = 0; i < word.length(); i++) { 32 | boolean isVowel = isVowel(word.toLowerCase().charAt(i)); 33 | if(prevNonVowel && isVowel && i != word.length() - 1) { 34 | syllables++; 35 | } 36 | prevNonVowel = !isVowel; 37 | } 38 | syllables = syllables == 0 ? 1 : syllables; 39 | return syllables; 40 | } 41 | 42 | private boolean isVowel(char letter) { 43 | return letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u'; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.analysis.kincaid/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.kincaid { 2 | requires easytext.analysis.api; 3 | 4 | exports javamodularity.easytext.analysis.kincaid; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.cli/javamodularity/easytext/cli/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.cli; 2 | 3 | import java.io.IOException; 4 | import java.nio.charset.Charset; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import javamodularity.easytext.analysis.factory.AnalyzerFactory; 12 | 13 | public class Main { 14 | 15 | public static void main(String... args) throws IOException { 16 | if (args.length == 0) { 17 | System.out.println("Welcome to EasyText. Please provide a filename as input argument"); 18 | return; 19 | } 20 | 21 | Path path = Paths.get(args[0]); 22 | System.out.println("Reading " + path); 23 | String text = new String(Files.readAllBytes(path), Charset.forName("UTF-8")); 24 | 25 | List> sentences = toSentences(text); 26 | 27 | for(String name: AnalyzerFactory.getSupportedAnalyses()) { 28 | System.out.println(name + ": " + AnalyzerFactory.getAnalyzer(name).analyze(sentences)); 29 | } 30 | 31 | } 32 | 33 | 34 | public static List> toSentences(String text) { 35 | String removedBreaks = text.replaceAll("\\r?\\n", " "); 36 | ArrayList> sentences = new ArrayList<>(); 37 | for(String rawSentence: removedBreaks.split("[\\.\\?\\!]")) { 38 | List words = toWords(rawSentence); 39 | if(words.size() > 0) { 40 | sentences.add(words); 41 | } 42 | } 43 | 44 | return sentences; 45 | } 46 | 47 | public static List toWords(String sentence) { 48 | String[] rawWords = sentence.split("\\s+"); 49 | List words = new ArrayList<>(); 50 | for(String rawWord: rawWords) { 51 | String word = rawWord.replaceAll("\\W", ""); 52 | if(word.length() > 0) { 53 | words.add(word); 54 | } 55 | } 56 | 57 | return words; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.cli/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.cli { 2 | requires easytext.analysis.api; 3 | requires easytext.analysis.factory; 4 | } 5 | -------------------------------------------------------------------------------- /chapter4/easytext-factory/src/easytext.gui/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.gui { 2 | 3 | exports javamodularity.easytext.gui to javafx.graphics; 4 | 5 | requires javafx.graphics; 6 | requires javafx.controls; 7 | requires easytext.analysis.api; 8 | requires easytext.analysis.factory; 9 | } 10 | -------------------------------------------------------------------------------- /chapter4/easytext-filtering/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the ServiceLoader.stream() method to select services based on a custom annotation. -------------------------------------------------------------------------------- /chapter4/easytext-filtering/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac -d mods --module-source-path src -m easytext.analysis.api,easytext.analysis.coleman,easytext.analysis.kincaid,easytext.filtering 4 | 5 | $JAVA_HOME/bin/java --module-path mods -m easytext.filtering/javamodularity.easytext.filtering.Main 6 | -------------------------------------------------------------------------------- /chapter4/easytext-filtering/src/easytext.analysis.api/javamodularity/easytext/analysis/api/Analyzer.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.api; 2 | 3 | import java.util.List; 4 | 5 | public interface Analyzer { 6 | 7 | String getName(); 8 | 9 | double analyze(List> text); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /chapter4/easytext-filtering/src/easytext.analysis.api/javamodularity/easytext/analysis/api/Fast.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.api; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface Fast { 8 | 9 | public boolean value() default true; 10 | 11 | } -------------------------------------------------------------------------------- /chapter4/easytext-filtering/src/easytext.analysis.api/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.api { 2 | exports javamodularity.easytext.analysis.api; 3 | } 4 | -------------------------------------------------------------------------------- /chapter4/easytext-filtering/src/easytext.analysis.coleman/javamodularity/easytext/analysis/coleman/Coleman.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.coleman; 2 | 3 | import javamodularity.easytext.analysis.api.Analyzer; 4 | import javamodularity.easytext.analysis.api.Fast; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | @Fast 10 | public class Coleman implements Analyzer { 11 | 12 | public static final String NAME = "Coleman-Liau"; 13 | 14 | @Override 15 | public String getName() { 16 | return NAME; 17 | } 18 | 19 | @Override 20 | public double analyze(List> sentences) { 21 | float totalsentences = sentences.size(); 22 | float words = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 23 | float letters = sentences.stream().flatMapToInt(sentence -> sentence.stream().mapToInt(word -> word.length())).sum(); 24 | 25 | return 0.0588 * (letters / (words / 100)) - 0.296 * (totalsentences / (words / 100)) - 15.8; 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /chapter4/easytext-filtering/src/easytext.analysis.coleman/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.coleman { 2 | requires easytext.analysis.api; 3 | 4 | provides javamodularity.easytext.analysis.api.Analyzer with javamodularity.easytext.analysis.coleman.Coleman; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-filtering/src/easytext.analysis.kincaid/javamodularity/easytext/analysis/kincaid/FleschKincaid.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.kincaid; 2 | 3 | import javamodularity.easytext.analysis.api.Analyzer; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class FleschKincaid implements Analyzer { 9 | 10 | public static final String NAME = "Flesch-Kincaid"; 11 | 12 | @Override 13 | public String getName() { 14 | return NAME; 15 | } 16 | 17 | @Override 18 | public double analyze(List> sentences) { 19 | float totalsentences = sentences.size(); 20 | float totalwords = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 21 | float totalsyllables = sentences.stream() 22 | .flatMapToInt(sentence -> 23 | sentence.stream().mapToInt(word -> countSyllables(word))) 24 | .sum(); 25 | return 206.835 - 1.015 * (totalwords / totalsentences) - 84.6 * (totalsyllables / totalwords); 26 | } 27 | 28 | private int countSyllables(String word) { 29 | int syllables = 0; 30 | boolean prevNonVowel = false; 31 | for(int i = 0; i < word.length(); i++) { 32 | boolean isVowel = isVowel(word.toLowerCase().charAt(i)); 33 | if(prevNonVowel && isVowel && i != word.length() - 1) { 34 | syllables++; 35 | } 36 | prevNonVowel = !isVowel; 37 | } 38 | syllables = syllables == 0 ? 1 : syllables; 39 | return syllables; 40 | } 41 | 42 | private boolean isVowel(char letter) { 43 | return letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u'; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /chapter4/easytext-filtering/src/easytext.analysis.kincaid/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.kincaid { 2 | requires easytext.analysis.api; 3 | 4 | provides javamodularity.easytext.analysis.api.Analyzer with javamodularity.easytext.analysis.kincaid.FleschKincaid; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-filtering/src/easytext.filtering/javamodularity/easytext/filtering/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.filtering; 2 | 3 | import java.util.ServiceLoader; 4 | import javamodularity.easytext.analysis.api.Analyzer; 5 | import javamodularity.easytext.analysis.api.Fast; 6 | 7 | public class Main { 8 | public static void main(String args[]) { 9 | ServiceLoader analyzers = 10 | ServiceLoader.load(Analyzer.class); 11 | 12 | analyzers.stream() 13 | .filter(provider -> isFast(provider.type())) 14 | .map(ServiceLoader.Provider::get) 15 | .forEach(analyzer -> System.out.println(analyzer.getName())); 16 | } 17 | 18 | private static boolean isFast(Class clazz) { 19 | return clazz.isAnnotationPresent(Fast.class) 20 | && clazz.getAnnotation(Fast.class).value() == true; 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /chapter4/easytext-filtering/src/easytext.filtering/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.filtering { 2 | requires easytext.analysis.api; 3 | 4 | uses javamodularity.easytext.analysis.api.Analyzer; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-services-factory/README.md: -------------------------------------------------------------------------------- 1 | This example is an example of providing a factory like API on an interface. 2 | The `Analyzer` interface provides the static `getAnalyzers()` method to easily get a list of implementations. -------------------------------------------------------------------------------- /chapter4/easytext-services-factory/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac --module-source-path src -d mods -m easytext.analysis.api,easytext.analysis.coleman,easytext.analysis.kincaid,easytext.cli 4 | 5 | $JAVA_HOME/bin/java --module-path mods -m easytext.cli/javamodularity.easytext.cli.Main ../exampletext.txt 6 | -------------------------------------------------------------------------------- /chapter4/easytext-services-factory/src/easytext.analysis.api/javamodularity/easytext/analysis/api/Analyzer.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.api; 2 | 3 | import java.util.List; 4 | import java.util.ServiceLoader; 5 | import java.util.stream.Stream; 6 | import java.util.stream.StreamSupport; 7 | 8 | public interface Analyzer { 9 | 10 | String getName(); 11 | 12 | double analyze(List> text); 13 | 14 | static Iterable getAnalyzers() { 15 | return ServiceLoader.load(Analyzer.class); // <1> 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /chapter4/easytext-services-factory/src/easytext.analysis.api/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.api { 2 | exports javamodularity.easytext.analysis.api; 3 | 4 | uses javamodularity.easytext.analysis.api.Analyzer; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-services-factory/src/easytext.analysis.coleman/javamodularity/easytext/analysis/coleman/Coleman.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.coleman; 2 | 3 | import javamodularity.easytext.analysis.api.Analyzer; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class Coleman implements Analyzer { 9 | 10 | public static final String NAME = "Coleman-Liau"; 11 | 12 | @Override 13 | public String getName() { 14 | return NAME; 15 | } 16 | 17 | @Override 18 | public double analyze(List> sentences) { 19 | float totalsentences = sentences.size(); 20 | float words = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 21 | float letters = sentences.stream().flatMapToInt(sentence -> sentence.stream().mapToInt(word -> word.length())).sum(); 22 | 23 | return 0.0588 * (letters / (words / 100)) - 0.296 * (totalsentences / (words / 100)) - 15.8; 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /chapter4/easytext-services-factory/src/easytext.analysis.coleman/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.coleman { 2 | requires easytext.analysis.api; 3 | 4 | provides javamodularity.easytext.analysis.api.Analyzer with javamodularity.easytext.analysis.coleman.Coleman; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-services-factory/src/easytext.analysis.kincaid/javamodularity/easytext/analysis/kincaid/FleschKincaid.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.kincaid; 2 | 3 | import javamodularity.easytext.analysis.api.Analyzer; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class FleschKincaid implements Analyzer { 9 | 10 | public static final String NAME = "Flesch-Kincaid"; 11 | 12 | @Override 13 | public String getName() { 14 | return NAME; 15 | } 16 | 17 | @Override 18 | public double analyze(List> sentences) { 19 | float totalsentences = sentences.size(); 20 | float totalwords = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 21 | float totalsyllables = sentences.stream() 22 | .flatMapToInt(sentence -> 23 | sentence.stream().mapToInt(word -> countSyllables(word))) 24 | .sum(); 25 | return 206.835 - 1.015 * (totalwords / totalsentences) - 84.6 * (totalsyllables / totalwords); 26 | } 27 | 28 | private int countSyllables(String word) { 29 | int syllables = 0; 30 | boolean prevNonVowel = false; 31 | for(int i = 0; i < word.length(); i++) { 32 | boolean isVowel = isVowel(word.toLowerCase().charAt(i)); 33 | if(prevNonVowel && isVowel && i != word.length() - 1) { 34 | syllables++; 35 | } 36 | prevNonVowel = !isVowel; 37 | } 38 | syllables = syllables == 0 ? 1 : syllables; 39 | return syllables; 40 | } 41 | 42 | private boolean isVowel(char letter) { 43 | return letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u'; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /chapter4/easytext-services-factory/src/easytext.analysis.kincaid/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.kincaid { 2 | requires easytext.analysis.api; 3 | 4 | provides javamodularity.easytext.analysis.api.Analyzer with javamodularity.easytext.analysis.kincaid.FleschKincaid; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-services-factory/src/easytext.cli/javamodularity/easytext/cli/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.cli; 2 | 3 | import java.io.IOException; 4 | import java.nio.charset.Charset; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.stream.Stream; 11 | 12 | import javamodularity.easytext.analysis.api.Analyzer; 13 | 14 | public class Main { 15 | 16 | public static void main(String... args) throws IOException { 17 | if (args.length == 0) { 18 | System.out.println("Welcome to EasyText. Please provide a filename as input argument"); 19 | return; 20 | } 21 | 22 | Path path = Paths.get(args[0]); 23 | System.out.println("Reading " + path); 24 | String text = new String(Files.readAllBytes(path), Charset.forName("UTF-8")); 25 | 26 | List> sentences = toSentences(text); 27 | 28 | 29 | Iterable analyzers = Analyzer.getAnalyzers(); 30 | 31 | for (Analyzer analyzer: analyzers) { 32 | System.out.println(analyzer.getName() + ": " + analyzer.analyze(sentences)); 33 | } 34 | } 35 | 36 | public static List> toSentences(String text) { 37 | String removedBreaks = text.replaceAll("\\r?\\n", " "); 38 | ArrayList> sentences = new ArrayList<>(); 39 | for(String rawSentence: removedBreaks.split("[\\.\\?\\!]")) { 40 | List words = toWords(rawSentence); 41 | if(words.size() > 0) { 42 | sentences.add(words); 43 | } 44 | } 45 | 46 | return sentences; 47 | } 48 | 49 | public static List toWords(String sentence) { 50 | String[] rawWords = sentence.split("\\s+"); 51 | List words = new ArrayList<>(); 52 | for(String rawWord: rawWords) { 53 | String word = rawWord.replaceAll("\\W", ""); 54 | if(word.length() > 0) { 55 | words.add(word); 56 | } 57 | } 58 | 59 | return words; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /chapter4/easytext-services-factory/src/easytext.cli/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.cli { 2 | requires easytext.analysis.api; 3 | } 4 | -------------------------------------------------------------------------------- /chapter4/easytext-services/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the use of services in the EasyText application. 2 | The application has both a gui and cli, both using services to use the analyzer implementations. -------------------------------------------------------------------------------- /chapter4/easytext-services/run-cli.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac --module-source-path src -d mods -m easytext.analysis.api,easytext.analysis.coleman,easytext.analysis.kincaid,easytext.cli 4 | 5 | $JAVA_HOME/bin/java --module-path mods -m easytext.cli/javamodularity.easytext.cli.Main ../exampletext.txt 6 | -------------------------------------------------------------------------------- /chapter4/easytext-services/run-gui.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac --module-source-path src -d mods -m easytext.analysis.api,easytext.analysis.coleman,easytext.analysis.kincaid,easytext.gui 4 | 5 | $JAVA_HOME/bin/java --module-path mods -m easytext.gui/javamodularity.easytext.gui.Main ../exampletext.txt 6 | -------------------------------------------------------------------------------- /chapter4/easytext-services/src/easytext.analysis.api/javamodularity/easytext/analysis/api/Analyzer.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.api; 2 | 3 | import java.util.List; 4 | 5 | public interface Analyzer { 6 | 7 | String getName(); 8 | 9 | double analyze(List> text); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /chapter4/easytext-services/src/easytext.analysis.api/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.api { 2 | exports javamodularity.easytext.analysis.api; 3 | } 4 | -------------------------------------------------------------------------------- /chapter4/easytext-services/src/easytext.analysis.coleman/javamodularity/easytext/analysis/coleman/Coleman.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.coleman; 2 | 3 | import javamodularity.easytext.analysis.api.Analyzer; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class Coleman implements Analyzer { 9 | 10 | public static final String NAME = "Coleman-Liau"; 11 | 12 | @Override 13 | public String getName() { 14 | return NAME; 15 | } 16 | 17 | @Override 18 | public double analyze(List> sentences) { 19 | float totalsentences = sentences.size(); 20 | float words = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 21 | float letters = sentences.stream().flatMapToInt(sentence -> sentence.stream().mapToInt(word -> word.length())).sum(); 22 | 23 | return 0.0588 * (letters / (words / 100)) - 0.296 * (totalsentences / (words / 100)) - 15.8; 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /chapter4/easytext-services/src/easytext.analysis.coleman/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.coleman { 2 | requires easytext.analysis.api; 3 | 4 | provides javamodularity.easytext.analysis.api.Analyzer with javamodularity.easytext.analysis.coleman.Coleman; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-services/src/easytext.analysis.kincaid/javamodularity/easytext/analysis/kincaid/FleschKincaid.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.kincaid; 2 | 3 | import javamodularity.easytext.analysis.api.Analyzer; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class FleschKincaid implements Analyzer { 9 | 10 | public static final String NAME = "Flesch-Kincaid"; 11 | 12 | @Override 13 | public String getName() { 14 | return NAME; 15 | } 16 | 17 | @Override 18 | public double analyze(List> sentences) { 19 | float totalsentences = sentences.size(); 20 | float totalwords = sentences.stream().mapToInt(sentence -> sentence.size()).sum(); 21 | float totalsyllables = sentences.stream() 22 | .flatMapToInt(sentence -> 23 | sentence.stream().mapToInt(word -> countSyllables(word))) 24 | .sum(); 25 | return 206.835 - 1.015 * (totalwords / totalsentences) - 84.6 * (totalsyllables / totalwords); 26 | } 27 | 28 | private int countSyllables(String word) { 29 | int syllables = 0; 30 | boolean prevNonVowel = false; 31 | for(int i = 0; i < word.length(); i++) { 32 | boolean isVowel = isVowel(word.toLowerCase().charAt(i)); 33 | if(prevNonVowel && isVowel && i != word.length() - 1) { 34 | syllables++; 35 | } 36 | prevNonVowel = !isVowel; 37 | } 38 | syllables = syllables == 0 ? 1 : syllables; 39 | return syllables; 40 | } 41 | 42 | private boolean isVowel(char letter) { 43 | return letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u'; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /chapter4/easytext-services/src/easytext.analysis.kincaid/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.kincaid { 2 | requires easytext.analysis.api; 3 | 4 | provides javamodularity.easytext.analysis.api.Analyzer with javamodularity.easytext.analysis.kincaid.FleschKincaid; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-services/src/easytext.cli/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.cli { 2 | requires easytext.analysis.api; 3 | 4 | uses javamodularity.easytext.analysis.api.Analyzer; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/easytext-services/src/easytext.gui/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.gui { 2 | 3 | exports javamodularity.easytext.gui to javafx.graphics; 4 | 5 | requires javafx.graphics; 6 | requires javafx.controls; 7 | requires easytext.analysis.api; 8 | 9 | uses javamodularity.easytext.analysis.api.Analyzer; 10 | } 11 | -------------------------------------------------------------------------------- /chapter4/providers/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the use of service provider methods. 2 | The `provider.factory.example` uses a provider method on a separate class to provide a service instance, while `provider.method.example` uses a provider method on the service implementation itself. -------------------------------------------------------------------------------- /chapter4/providers/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac --module-source-path src -d mods -m main,provider.method.example,provider.factory.example 4 | $JAVA_HOME/bin/java --module-path mods -m main/javamodularity.providers.main.Main 5 | -------------------------------------------------------------------------------- /chapter4/providers/src/easytext.analysis.api/javamodularity/easytext/analysis/api/Analyzer.java: -------------------------------------------------------------------------------- 1 | package javamodularity.easytext.analysis.api; 2 | 3 | import java.util.List; 4 | 5 | public interface Analyzer { 6 | 7 | String getName(); 8 | 9 | double analyze(List> text); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /chapter4/providers/src/easytext.analysis.api/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.analysis.api { 2 | exports javamodularity.easytext.analysis.api; 3 | } 4 | -------------------------------------------------------------------------------- /chapter4/providers/src/main/javamodularity/providers/main/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.providers.main; 2 | 3 | import java.util.List; 4 | import javamodularity.easytext.analysis.api.Analyzer; 5 | import java.util.ServiceLoader; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | Iterable analyzers = ServiceLoader.load(Analyzer.class); 10 | 11 | for (Analyzer analyzer : analyzers) { 12 | System.out.println(analyzer.getName()); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /chapter4/providers/src/main/module-info.java: -------------------------------------------------------------------------------- 1 | module main { 2 | requires easytext.analysis.api; 3 | 4 | uses javamodularity.easytext.analysis.api.Analyzer; 5 | } 6 | -------------------------------------------------------------------------------- /chapter4/providers/src/provider.factory.example/javamodularity/providers/factory/ExampleProvider.java: -------------------------------------------------------------------------------- 1 | package javamodularity.providers.factory; 2 | 3 | import java.util.List; 4 | import javamodularity.easytext.analysis.api.Analyzer; 5 | 6 | class ExampleProvider implements Analyzer { 7 | 8 | private String name; 9 | 10 | public ExampleProvider(String name) { 11 | this.name = name; 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | @Override 20 | public double analyze(List> sentences) { 21 | return 0; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /chapter4/providers/src/provider.factory.example/javamodularity/providers/factory/ExampleProviderFactory.java: -------------------------------------------------------------------------------- 1 | package javamodularity.providers.factory; 2 | 3 | public class ExampleProviderFactory { 4 | public static ExampleProvider provider() { 5 | return new ExampleProvider("Analyzer created by factory"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /chapter4/providers/src/provider.factory.example/module-info.java: -------------------------------------------------------------------------------- 1 | module provider.factory.example { 2 | requires easytext.analysis.api; 3 | 4 | provides javamodularity.easytext.analysis.api.Analyzer 5 | with javamodularity.providers.factory.ExampleProviderFactory; 6 | } 7 | -------------------------------------------------------------------------------- /chapter4/providers/src/provider.method.example/javamodularity/providers/method/ExampleProviderMethod.java: -------------------------------------------------------------------------------- 1 | package javamodularity.providers.method; 2 | 3 | import java.util.List; 4 | import javamodularity.easytext.analysis.api.Analyzer; 5 | 6 | public class ExampleProviderMethod implements Analyzer { 7 | 8 | private String name; 9 | 10 | ExampleProviderMethod(String name) { 11 | this.name = name; 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | @Override 20 | public double analyze(List> sentences) { 21 | return 0; 22 | } 23 | 24 | public static ExampleProviderMethod provider() { 25 | return new ExampleProviderMethod("Analyzer created by static method"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /chapter4/providers/src/provider.method.example/module-info.java: -------------------------------------------------------------------------------- 1 | module provider.method.example { 2 | requires easytext.analysis.api; 3 | 4 | provides javamodularity.easytext.analysis.api.Analyzer 5 | with javamodularity.providers.method.ExampleProviderMethod; 6 | } 7 | -------------------------------------------------------------------------------- /chapter5/cyclic_dependencies/README.md: -------------------------------------------------------------------------------- 1 | This is an example of code that contains a cycle, and a possible way to refactor the code. The `cycle` example can't compile without refactoring. 2 | -------------------------------------------------------------------------------- /chapter5/cyclic_dependencies/cycle/src/authors/Author.java: -------------------------------------------------------------------------------- 1 | package authors; 2 | 3 | import books.Book; 4 | 5 | import java.util.List; 6 | import java.util.ArrayList; 7 | 8 | public class Author { 9 | private String name; 10 | private List books = new ArrayList<>(); 11 | 12 | public Author(String name) { 13 | this.name = name; 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public void writeBook(String title, String text) { 21 | this.books.add(new Book(this, title, text)); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /chapter5/cyclic_dependencies/cycle/src/books/Book.java: -------------------------------------------------------------------------------- 1 | package books; 2 | 3 | import authors.Author; 4 | 5 | public class Book { 6 | private Author author; 7 | private String title; 8 | private String text; 9 | 10 | public Book(Author author, String title, String text) { 11 | this.author = author; 12 | this.text = text; 13 | this.title = title; 14 | } 15 | 16 | public void printBook() { 17 | System.out.printf("%s, by %s\n\n%s", title, author.getName(), text); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chapter5/cyclic_dependencies/without_cycle/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac --module-source-path src -d mods -m authors,books -------------------------------------------------------------------------------- /chapter5/cyclic_dependencies/without_cycle/src/authors/javamodularity/authors/Author.java: -------------------------------------------------------------------------------- 1 | package javamodularity.authors; 2 | 3 | import javamodularity.books.Book; 4 | import javamodularity.books.Named; 5 | 6 | import java.util.List; 7 | import java.util.ArrayList; 8 | 9 | public class Author implements Named { 10 | private String name; 11 | private List books = new ArrayList<>(); 12 | 13 | public Author(String name) { 14 | this.name = name; 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void writeBook(String title, String text) { 23 | this.books.add(new Book(this, title, text)); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /chapter5/cyclic_dependencies/without_cycle/src/authors/module-info.java: -------------------------------------------------------------------------------- 1 | module authors { 2 | requires books; 3 | } 4 | -------------------------------------------------------------------------------- /chapter5/cyclic_dependencies/without_cycle/src/books/javamodularity/books/Book.java: -------------------------------------------------------------------------------- 1 | package javamodularity.books; 2 | 3 | public class Book { 4 | private Named author; 5 | private String title; 6 | private String text; 7 | 8 | public Book(Named author, String title, String text) { 9 | this.author = author; 10 | this.text = text; 11 | this.title = title; 12 | } 13 | 14 | public void printBook() { 15 | System.out.printf("%s, by %s\n\n%s", title, author.getName(), text); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /chapter5/cyclic_dependencies/without_cycle/src/books/javamodularity/books/Named.java: -------------------------------------------------------------------------------- 1 | package javamodularity.books; 2 | 3 | public interface Named { 4 | String getName(); 5 | } 6 | -------------------------------------------------------------------------------- /chapter5/cyclic_dependencies/without_cycle/src/books/module-info.java: -------------------------------------------------------------------------------- 1 | module books { 2 | exports javamodularity.books; 3 | } 4 | -------------------------------------------------------------------------------- /chapter5/implied_readability/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the need for `requires transitive`. The example demonstrates the error, so it does not compile without changes. -------------------------------------------------------------------------------- /chapter5/implied_readability/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac --module-source-path src -d mods -m easytext.client,easytext.domain.api,easytext.repository.api 4 | -------------------------------------------------------------------------------- /chapter5/implied_readability/src/easytext.client/easytext/client/Client.java: -------------------------------------------------------------------------------- 1 | package easytext.client; 2 | 3 | import java.util.ServiceLoader; 4 | 5 | import easytext.repository.api.TextRepository; 6 | 7 | public class Client { 8 | 9 | public static void main(String... args) { 10 | TextRepository repository = ServiceLoader.load(TextRepository.class) 11 | .iterator().next(); 12 | 13 | repository.findText("HHGTTG").wordcount(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /chapter5/implied_readability/src/easytext.client/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.client { 2 | 3 | requires easytext.repository.api; 4 | 5 | uses easytext.repository.api.TextRepository; 6 | } 7 | -------------------------------------------------------------------------------- /chapter5/implied_readability/src/easytext.domain.api/easytext/domain/api/Text.java: -------------------------------------------------------------------------------- 1 | package easytext.domain.api; 2 | 3 | public class Text { 4 | 5 | private String theText; 6 | 7 | public String getTheText() { 8 | return this.theText; 9 | } 10 | 11 | public void setTheText(String theText) { 12 | this.theText = theText; 13 | } 14 | 15 | public int wordcount() { 16 | return 42; // Why not 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter5/implied_readability/src/easytext.domain.api/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.domain.api { 2 | exports easytext.domain.api; 3 | } 4 | -------------------------------------------------------------------------------- /chapter5/implied_readability/src/easytext.repository.api/easytext/repository/api/TextRepository.java: -------------------------------------------------------------------------------- 1 | package easytext.repository.api; 2 | 3 | import easytext.domain.api.Text; 4 | 5 | public interface TextRepository { 6 | Text findText(String id); 7 | } 8 | -------------------------------------------------------------------------------- /chapter5/implied_readability/src/easytext.repository.api/module-info.java: -------------------------------------------------------------------------------- 1 | module easytext.repository.api { 2 | exports easytext.repository.api; 3 | requires easytext.domain.api; 4 | } 5 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the use of `requries static` to create optional dependencies. 2 | This requires loading code dynamically as well, which is demonstrated in `framework/javamodularity.framework.Main.java`. 3 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac --module-source-path src -d mods -m fastjsonlib,framework 4 | $JAVA_HOME/bin/java --module-path mods --add-modules fastjsonlib -m framework/javamodularity.framework.Main 5 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies/src/fastjsonlib/javamodularity/fastjsonlib/FastJson.java: -------------------------------------------------------------------------------- 1 | package javamodularity.fastjsonlib; 2 | 3 | public class FastJson { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies/src/fastjsonlib/module-info.java: -------------------------------------------------------------------------------- 1 | module fastjsonlib { 2 | exports javamodularity.fastjsonlib; 3 | } 4 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies/src/framework/javamodularity/framework/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.framework; 2 | 3 | import javamodularity.fastjsonlib.FastJson; 4 | 5 | public class Main { 6 | 7 | public static void main(String... args) { 8 | try { 9 | Class clazz = Class.forName("javamodularity.fastjsonlib.FastJson"); 10 | FastJson instance = 11 | (FastJson) clazz.getConstructor().newInstance(); 12 | System.out.println("Using FastJson"); 13 | } catch (ReflectiveOperationException e) { 14 | System.out.println("Oops, we need a fallback!"); 15 | } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies/src/framework/javamodularity/framework/MainBad.java: -------------------------------------------------------------------------------- 1 | package javamodularity.framework; 2 | 3 | import javamodularity.fastjsonlib.FastJson; 4 | 5 | public class MainBad { 6 | 7 | public static void main(String... args) { 8 | FastJson fastJson = new FastJson(); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies/src/framework/module-info.java: -------------------------------------------------------------------------------- 1 | module framework { 2 | requires static fastjsonlib; 3 | } 4 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_annotations/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the use of `requries static` for compile time annotation processing. 2 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_annotations/run.sh: -------------------------------------------------------------------------------- 1 | javac --module-source-path src -d out -m application,schemagenerator 2 | 3 | # Exclude myannotations module from the run-time classpath 4 | java -ea --module-path out/application -m application/javamodularity.application.Main 5 | 6 | # Include myannotations module, expected: AssertionError 7 | java -ea --module-path out --add-modules schemagenerator -m application/javamodularity.application.Main 8 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_annotations/src/application/javamodularity/application/BookEntity.java: -------------------------------------------------------------------------------- 1 | package javamodularity.application; 2 | 3 | import javamodularity.schemagenerator.GenerateSchema; 4 | 5 | @GenerateSchema 6 | public class BookEntity { 7 | 8 | public String title; 9 | public String[] authors; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_annotations/src/application/javamodularity/application/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.application; 2 | 3 | public class Main { 4 | public static void main(String... args) { 5 | BookEntity b = new BookEntity(); 6 | assert BookEntity.class.getAnnotations().length == 0; 7 | System.out.println("Running without annotation @GenerateSchema present."); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_annotations/src/application/module-info.java: -------------------------------------------------------------------------------- 1 | module application { 2 | requires static schemagenerator; 3 | } 4 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_annotations/src/schemagenerator/javamodularity/schemagenerator/GenerateSchema.java: -------------------------------------------------------------------------------- 1 | package javamodularity.schemagenerator; 2 | 3 | import java.lang.annotation.*; 4 | import static java.lang.annotation.ElementType.*; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | @Target(value={TYPE}) 8 | public @interface GenerateSchema { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_annotations/src/schemagenerator/module-info.java: -------------------------------------------------------------------------------- 1 | module schemagenerator { 2 | exports javamodularity.schemagenerator; 3 | } 4 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_service/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates an alternative approach for optional dependencies based on services. -------------------------------------------------------------------------------- /chapter5/optional_dependencies_service/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac --module-source-path src -d mods -m fastjsonlib,framework 4 | 5 | $JAVA_HOME/bin/java --module-path mods -m framework/javamodularity.framework.Main -------------------------------------------------------------------------------- /chapter5/optional_dependencies_service/src/fastjsonlib/javamodularity/fastjsonlib/FastJson.java: -------------------------------------------------------------------------------- 1 | package javamodularity.fastjsonlib; 2 | 3 | public class FastJson { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_service/src/fastjsonlib/module-info.java: -------------------------------------------------------------------------------- 1 | module fastjsonlib { 2 | exports javamodularity.fastjsonlib; 3 | provides javamodularity.fastjsonlib.FastJson 4 | with javamodularity.fastjsonlib.FastJson; 5 | } 6 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_service/src/framework/javamodularity/framework/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.framework; 2 | 3 | import java.util.Iterator; 4 | import java.util.ServiceLoader; 5 | 6 | import javamodularity.fastjsonlib.FastJson; 7 | 8 | public class Main { 9 | 10 | public static void main(String... args) { 11 | FastJson fastJson = 12 | ServiceLoader.load(FastJson.class) 13 | .findFirst() 14 | .orElse(getFallBack()); 15 | 16 | if(fastJson == null) { 17 | System.out.println("Using a fallback"); 18 | } else { 19 | System.out.println("Found a service"); 20 | } 21 | } 22 | 23 | private static FastJson getFallBack() { 24 | return null; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /chapter5/optional_dependencies_service/src/framework/module-info.java: -------------------------------------------------------------------------------- 1 | module framework { 2 | requires static fastjsonlib; 3 | uses javamodularity.fastjsonlib.FastJson; 4 | } 5 | -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates different ways of loading resources from modules. 2 | Note that running the example doesn't print anything. -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/run.sh: -------------------------------------------------------------------------------- 1 | rm -rf out 2 | 3 | # Copy resources 4 | cd src 5 | rsync -Rq $(find . -name *.txt) ../out 6 | cd - 7 | 8 | # Compile modules 9 | javac -Xlint:unchecked \ 10 | --module-source-path src \ 11 | -d out $(find src -name '*.java') \ 12 | && \ 13 | java -p out -ea \ 14 | --add-modules secondresourcemodule \ 15 | -m firstresourcemodule/javamodularity.firstresourcemodule.ResourcesInModule \ 16 | && \ 17 | java -p out -ea \ 18 | --add-modules secondresourcemodule \ 19 | -m firstresourcemodule/javamodularity.firstresourcemodule.ResourcesOtherModule 20 | -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/firstresourcemodule/javamodularity/firstresourcemodule/ResourcesInModule.java: -------------------------------------------------------------------------------- 1 | package javamodularity.firstresourcemodule; 2 | 3 | import java.util.Optional; 4 | import java.util.Arrays; 5 | import java.util.Objects; 6 | import java.util.stream.Stream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.lang.RuntimeException; 10 | import java.net.URL; 11 | 12 | public class ResourcesInModule { 13 | 14 | public static void main(String... args) throws Exception { 15 | Class clazz = ResourcesInModule.class; 16 | InputStream cz_pkg = clazz.getResourceAsStream("resource_in_package.txt"); //<1> 17 | URL cz_tl = clazz.getResource("/top_level_resource.txt"); //<2> 18 | 19 | Module m = clazz.getModule(); //<3> 20 | InputStream m_pkg = m.getResourceAsStream( 21 | "javamodularity/firstresourcemodule/resource_in_package.txt"); //<4> 22 | InputStream m_tl = m.getResourceAsStream("top_level_resource.txt"); //<5> 23 | 24 | assert Stream.of(cz_pkg, cz_tl, m_pkg, m_tl) 25 | .noneMatch(Objects::isNull); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/firstresourcemodule/javamodularity/firstresourcemodule/ResourcesOtherModule.java: -------------------------------------------------------------------------------- 1 | package javamodularity.firstresourcemodule; 2 | 3 | import java.lang.ClassLoader; 4 | import java.util.*; 5 | import java.util.stream.Stream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.lang.RuntimeException; 9 | 10 | public class ResourcesOtherModule { 11 | 12 | public static void main(String... args) throws Exception { 13 | Optional otherModule = ModuleLayer.boot().findModule("secondresourcemodule"); //<1> 14 | 15 | otherModule.ifPresent(other -> { 16 | try { 17 | InputStream m_tl = other.getResourceAsStream("top_level_resource2.txt"); //<2> 18 | InputStream m_pkg = other.getResourceAsStream( 19 | "javamodularity/secondresourcemodule/resource_in_package2.txt"); //<3> 20 | InputStream m_class = other.getResourceAsStream( 21 | "javamodularity/secondresourcemodule/A.class"); //<4> 22 | InputStream m_meta = other.getResourceAsStream("META-INF/resource_in_metainf.txt"); //<5> 23 | InputStream cz_pkg = 24 | Class.forName("javamodularity.secondresourcemodule.A") 25 | .getResourceAsStream("resource_in_package2.txt"); //<6> 26 | 27 | assert Stream.of(m_tl, m_class, m_meta) 28 | .noneMatch(Objects::isNull); 29 | assert Stream.of(m_pkg, cz_pkg) 30 | .allMatch(Objects::isNull); 31 | 32 | } catch (Exception e) { 33 | throw new RuntimeException(e); 34 | } 35 | }); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/firstresourcemodule/javamodularity/firstresourcemodule/resource_in_package.txt: -------------------------------------------------------------------------------- 1 | A resource in a package directory -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/firstresourcemodule/module-info.java: -------------------------------------------------------------------------------- 1 | module firstresourcemodule {} 2 | -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/firstresourcemodule/top_level_resource.txt: -------------------------------------------------------------------------------- 1 | A top-level resource in the module. -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/secondresourcemodule/META-INF/resource_in_metainf.txt: -------------------------------------------------------------------------------- 1 | A resource in a the META-INF directory 2 | -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/secondresourcemodule/foo/foo.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter5/resource_encapsulation/src/secondresourcemodule/foo/foo.txt -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/secondresourcemodule/javamodularity/secondresourcemodule/A.java: -------------------------------------------------------------------------------- 1 | package javamodularity.secondresourcemodule; 2 | 3 | public class A { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/secondresourcemodule/javamodularity/secondresourcemodule/resource_in_package2.txt: -------------------------------------------------------------------------------- 1 | A resource in a package directory -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/secondresourcemodule/module-info.java: -------------------------------------------------------------------------------- 1 | module secondresourcemodule {} 2 | -------------------------------------------------------------------------------- /chapter5/resource_encapsulation/src/secondresourcemodule/top_level_resource2.txt: -------------------------------------------------------------------------------- 1 | Another top-level resource. -------------------------------------------------------------------------------- /chapter5/resourcebundles/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates providing resources from a module using services and the `ResourceBundleProvider` API. -------------------------------------------------------------------------------- /chapter5/resourcebundles/run.sh: -------------------------------------------------------------------------------- 1 | rm -rf out 2 | mkdir out 3 | 4 | # Copy resources 5 | cd src 6 | rsync -Rq $(find . -name *.properties) ../out 7 | cd - 8 | 9 | # Compile modules 10 | javac -Xlint:unchecked \ 11 | --module-source-path src \ 12 | -d out $(find src -name '*.java') \ 13 | && \ 14 | java -p out \ 15 | --add-modules resourcebundle.main \ 16 | --add-modules resourcebundle.dutch \ 17 | -m resourcebundle.main/javamodularity.resourcebundle.Loader $1 # en-GB or nl-NL 18 | -------------------------------------------------------------------------------- /chapter5/resourcebundles/src/resourcebundle.dutch/javamodularity/resourcebundle/dutch/DutchTranslationsProvider.java: -------------------------------------------------------------------------------- 1 | package javamodularity.resourcebundle.dutch; 2 | 3 | import java.util.Locale; 4 | import java.util.ResourceBundle; 5 | import java.util.spi.AbstractResourceBundleProvider; 6 | 7 | import javamodularity.resourcebundle.spi.TranslationsProvider; 8 | 9 | public class DutchTranslationsProvider extends AbstractResourceBundleProvider 10 | implements TranslationsProvider { 11 | 12 | private static Locale DUTCH = Locale.forLanguageTag("nl"); 13 | 14 | @Override 15 | public String toBundleName(String baseName, Locale locale) { 16 | String bundleName = super.toBundleName(baseName, locale); 17 | if (DUTCH.equals(locale)) { 18 | int index = bundleName.lastIndexOf('.'); 19 | return bundleName.substring(0, index + 1) + "dutch" + bundleName.substring(index); 20 | } 21 | return bundleName; 22 | } 23 | 24 | @Override 25 | public ResourceBundle getBundle(String baseName, Locale locale) { 26 | if (DUTCH.equals(locale)) { 27 | return super.getBundle(baseName, locale); 28 | } 29 | return null; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /chapter5/resourcebundles/src/resourcebundle.dutch/javamodularity/resourcebundle/dutch/Translations_nl.properties: -------------------------------------------------------------------------------- 1 | modularity_key=modulariteit 2 | -------------------------------------------------------------------------------- /chapter5/resourcebundles/src/resourcebundle.dutch/module-info.java: -------------------------------------------------------------------------------- 1 | module resourcebundle.dutch { 2 | requires resourcebundle.main; 3 | 4 | provides javamodularity.resourcebundle.spi.TranslationsProvider 5 | with javamodularity.resourcebundle.dutch.DutchTranslationsProvider; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /chapter5/resourcebundles/src/resourcebundle.main/javamodularity/resourcebundle/Loader.java: -------------------------------------------------------------------------------- 1 | package javamodularity.resourcebundle; 2 | 3 | import java.util.Locale; 4 | import java.util.ResourceBundle; 5 | 6 | public class Loader { 7 | 8 | public static void main(String... args) throws Exception { 9 | String locale = args.length > 0 ? args[0] : "en-GB"; 10 | Locale l = Locale.forLanguageTag(locale); 11 | ResourceBundle translations = 12 | ResourceBundle.getBundle("javamodularity.resourcebundle.Translations", l); 13 | 14 | System.out.println("Translation of modularity in " + l 15 | + ": " + translations.getString("modularity_key")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /chapter5/resourcebundles/src/resourcebundle.main/javamodularity/resourcebundle/Translations_en.properties: -------------------------------------------------------------------------------- 1 | modularity_key=modularity 2 | -------------------------------------------------------------------------------- /chapter5/resourcebundles/src/resourcebundle.main/javamodularity/resourcebundle/spi/TranslationsProvider.java: -------------------------------------------------------------------------------- 1 | package javamodularity.resourcebundle.spi; 2 | 3 | import java.util.spi.ResourceBundleProvider; 4 | 5 | public interface TranslationsProvider extends ResourceBundleProvider { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /chapter5/resourcebundles/src/resourcebundle.main/module-info.java: -------------------------------------------------------------------------------- 1 | module resourcebundle.main { 2 | exports javamodularity.resourcebundle.spi; 3 | 4 | uses javamodularity.resourcebundle.spi.TranslationsProvider; 5 | 6 | } 7 | -------------------------------------------------------------------------------- /chapter6/annotated_module/README.md: -------------------------------------------------------------------------------- 1 | This is an exmaple of using an (custom) annotation on a module definition. -------------------------------------------------------------------------------- /chapter6/annotated_module/src/annotated/javamodularity/annotatedmodule/CustomAnnotation.java: -------------------------------------------------------------------------------- 1 | package javamodularity.annotatedmodule; 2 | 3 | import java.lang.annotation.*; 4 | import static java.lang.annotation.ElementType.*; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | @Target(value={PACKAGE, MODULE}) 8 | public @interface CustomAnnotation { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /chapter6/annotated_module/src/annotated/module-info.java: -------------------------------------------------------------------------------- 1 | import javamodularity.annotatedmodule.CustomAnnotation; 2 | 3 | @CustomAnnotation 4 | module annotated { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /chapter6/bootlayer/README.md: -------------------------------------------------------------------------------- 1 | This example prints all modules in the boot layer, and module's classloader. -------------------------------------------------------------------------------- /chapter6/bootlayer/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac --module-source-path src -d mods -m application 4 | 5 | $JAVA_HOME/bin/java --module-path mods -m application/javamodularity.application.Main 6 | -------------------------------------------------------------------------------- /chapter6/bootlayer/src/application/javamodularity/application/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.application; 2 | 3 | import java.sql.Driver; 4 | 5 | public class Main { 6 | 7 | public static void main(String... args) { 8 | Driver driver = null; // We reference java.sql.Driver to see 'java.sql' gets resolved 9 | ModuleLayer.boot().modules().forEach(m -> System.out.println(m.getName() + ", loader: " + m.getClassLoader())); 10 | System.out.println("System classloader: " + ClassLoader.getSystemClassLoader()); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /chapter6/bootlayer/src/application/module-info.java: -------------------------------------------------------------------------------- 1 | module application { 2 | requires java.sql; 3 | } 4 | -------------------------------------------------------------------------------- /chapter6/container/README.md: -------------------------------------------------------------------------------- 1 | This is an example implementation of a container. 2 | The two example apps are loaded in the container. 3 | After starting the container, the example apps can be deployed/undeployed with the `deploy ` and `undeploy commands`. -------------------------------------------------------------------------------- /chapter6/container/run.sh: -------------------------------------------------------------------------------- 1 | rm -rf out-app/ out-container/ 2 | 3 | # Compile container and platform API first 4 | javac -Xlint:deprecation -Xlint:unchecked --module-source-path src-container -d out-container -m platform.api,platform.container 5 | 6 | # Compile app a with platform API in separate output directory 7 | javac -Xlint:deprecation --module-path out-container/platform.api --module-source-path src-appa -d out-appa -m app.a 8 | 9 | # Compile app b with platform API in separate output directory 10 | javac -Xlint:deprecation --module-path out-container/platform.api --module-source-path src-appb -d out-appb -m app.b 11 | 12 | # Run the container app, without putting the compiled modules of the app on the module path. 13 | # These are loaded by the container as applications! 14 | java --module-path out-container --add-modules ALL-SYSTEM -m platform.container/platform.container.Launcher out-appa/app.a/app.a.AppA out-appb/app.b/app.b.AppB 15 | -------------------------------------------------------------------------------- /chapter6/container/src-appa/app.a/app/NonUniqueName.java: -------------------------------------------------------------------------------- 1 | package app; 2 | 3 | public class NonUniqueName { 4 | public static final String TEXT = "Same fully qualified class name, different module"; 5 | } 6 | -------------------------------------------------------------------------------- /chapter6/container/src-appa/app.a/app/a/AppA.java: -------------------------------------------------------------------------------- 1 | package app.a; 2 | 3 | import java.util.concurrent.Executors; 4 | import java.util.concurrent.ScheduledExecutorService; 5 | import java.util.concurrent.ScheduledFuture; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | import platform.api.ContainerApplication; 9 | 10 | import app.a.internal.Worker; 11 | 12 | public class AppA implements ContainerApplication { 13 | 14 | ScheduledExecutorService executor; 15 | ScheduledFuture scheduledFuture; 16 | 17 | public void startApp() { 18 | System.out.println("Starting App A"); 19 | executor = Executors.newScheduledThreadPool(1); 20 | scheduledFuture = 21 | executor.scheduleAtFixedRate(new Worker(), 2L, 12L, TimeUnit.SECONDS); 22 | } 23 | 24 | public void stopApp() { 25 | scheduledFuture.cancel(false); 26 | executor = null; 27 | System.out.println("Stopping App A"); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /chapter6/container/src-appa/app.a/app/a/internal/Worker.java: -------------------------------------------------------------------------------- 1 | package app.a.internal; 2 | 3 | import platform.api.tx.TransactionManager; 4 | 5 | public class Worker implements Runnable { 6 | 7 | TransactionManager txMgr; 8 | 9 | public Worker() { 10 | txMgr = TransactionManager.getTransactionManagers().next(); 11 | } 12 | 13 | public void run() { 14 | long txId = txMgr.start(); 15 | System.out.println("App A doing work within tx " + txId); 16 | txMgr.commit(txId); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter6/container/src-appa/app.a/module-info.java: -------------------------------------------------------------------------------- 1 | module app.a { 2 | requires platform.api; 3 | } 4 | -------------------------------------------------------------------------------- /chapter6/container/src-appb/app.b/app/NonUniqueName.java: -------------------------------------------------------------------------------- 1 | package app; 2 | 3 | public class NonUniqueName { 4 | public static final String TEXT = "Same fully qualified class name, different module"; 5 | } 6 | -------------------------------------------------------------------------------- /chapter6/container/src-appb/app.b/app/b/AppB.java: -------------------------------------------------------------------------------- 1 | package app.b; 2 | 3 | import java.util.concurrent.Executors; 4 | import java.util.concurrent.ScheduledExecutorService; 5 | import java.util.concurrent.ScheduledFuture; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | import platform.api.ContainerApplication; 9 | 10 | import app.b.internal.Worker; 11 | 12 | public class AppB implements ContainerApplication { 13 | 14 | ScheduledExecutorService executor; 15 | ScheduledFuture scheduledFuture; 16 | 17 | public void startApp() { 18 | System.out.println("Starting App B"); 19 | executor = Executors.newScheduledThreadPool(1); 20 | scheduledFuture = 21 | executor.scheduleAtFixedRate(new Worker(), 1L, 10L, TimeUnit.SECONDS); 22 | } 23 | 24 | public void stopApp() { 25 | scheduledFuture.cancel(false); 26 | executor = null; 27 | System.out.println("Stopping App B"); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /chapter6/container/src-appb/app.b/app/b/internal/Worker.java: -------------------------------------------------------------------------------- 1 | package app.b.internal; 2 | 3 | import platform.api.tx.TransactionManager; 4 | 5 | public class Worker implements Runnable { 6 | 7 | TransactionManager txMgr; 8 | 9 | public Worker() { 10 | txMgr = TransactionManager.getTransactionManagers().next(); 11 | } 12 | 13 | public void run() { 14 | long txId = txMgr.start(); 15 | System.out.println("App B doing work within tx " + txId); 16 | txMgr.commit(txId); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter6/container/src-appb/app.b/module-info.java: -------------------------------------------------------------------------------- 1 | module app.b { 2 | requires platform.api; 3 | } 4 | -------------------------------------------------------------------------------- /chapter6/container/src-container/platform.api/module-info.java: -------------------------------------------------------------------------------- 1 | module platform.api { 2 | exports platform.api; 3 | exports platform.api.tx; 4 | 5 | uses platform.api.tx.TransactionManager; 6 | } 7 | -------------------------------------------------------------------------------- /chapter6/container/src-container/platform.api/platform/api/ContainerApplication.java: -------------------------------------------------------------------------------- 1 | package platform.api; 2 | 3 | public interface ContainerApplication { 4 | void startApp(); 5 | void stopApp(); 6 | } 7 | -------------------------------------------------------------------------------- /chapter6/container/src-container/platform.api/platform/api/tx/TransactionManager.java: -------------------------------------------------------------------------------- 1 | package platform.api.tx; 2 | 3 | import java.util.Iterator; 4 | import java.util.ServiceLoader; 5 | 6 | public interface TransactionManager { 7 | 8 | long start(); 9 | 10 | void commit(long txId); 11 | 12 | void rollback(long txId); 13 | 14 | static Iterator getTransactionManagers() { 15 | return ServiceLoader.load(TransactionManager.class).iterator(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /chapter6/container/src-container/platform.container/module-info.java: -------------------------------------------------------------------------------- 1 | module platform.container { 2 | requires platform.api; 3 | 4 | provides platform.api.tx.TransactionManager 5 | with platform.container.tx.SimpleTransactionManager; 6 | } 7 | -------------------------------------------------------------------------------- /chapter6/container/src-container/platform.container/platform/container/AppDescriptor.java: -------------------------------------------------------------------------------- 1 | package platform.container; 2 | 3 | import java.io.File; 4 | 5 | public class AppDescriptor { 6 | public final String appDir; 7 | public final String rootmodule; 8 | public final String appClass; 9 | public final String appClassPkg; 10 | 11 | public AppDescriptor(String unparsed) { 12 | int firstSlash = unparsed.indexOf(File.separator); 13 | int lastSlash = unparsed.lastIndexOf(File.separator); 14 | rootmodule = unparsed.substring(firstSlash + 1, lastSlash); 15 | appDir = unparsed.substring(0, lastSlash); 16 | appClass = unparsed.substring(lastSlash + 1); 17 | appClassPkg = appClass.substring(0, appClass.lastIndexOf('.')); 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return String.format("{ rootmodule: %s, appClass: %s, appDir: %s}", 23 | rootmodule, appClass, appDir); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /chapter6/container/src-container/platform.container/platform/container/tx/SimpleTransactionManager.java: -------------------------------------------------------------------------------- 1 | package platform.container.tx; 2 | 3 | import java.util.concurrent.atomic.AtomicLong; 4 | import platform.api.tx.TransactionManager; 5 | 6 | public class SimpleTransactionManager implements TransactionManager { 7 | 8 | private AtomicLong nextTxId = new AtomicLong(); 9 | 10 | @Override 11 | public long start() { 12 | return nextTxId.getAndIncrement(); 13 | } 14 | 15 | @Override 16 | public void commit(long txId) { 17 | if(txId >= nextTxId.get()) 18 | throw new IllegalStateException("Cannot commit tx with unknown id " + txId); 19 | 20 | System.out.println("Committing tx with id " + txId); 21 | } 22 | 23 | @Override 24 | public void rollback(long txId) { 25 | if(txId >= nextTxId.get()) 26 | throw new IllegalStateException("Cannot rollback tx with unknown id " + txId); 27 | 28 | System.out.println("Rolling back tx with id " + txId); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /chapter6/introspection/README.md: -------------------------------------------------------------------------------- 1 | This exmaple demonstrates the introspection APIs available for modules. -------------------------------------------------------------------------------- /chapter6/introspection/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac -d out -sourcepath src $(find src -name '*.java') 4 | $JAVA_HOME/bin/java -cp out javamodularity.introspection.Introspection -------------------------------------------------------------------------------- /chapter6/introspection/src/javamodularity/introspection/Introspection.java: -------------------------------------------------------------------------------- 1 | package javamodularity.introspection; 2 | 3 | import java.util.*; 4 | import java.lang.module.*; 5 | import java.lang.module.ModuleDescriptor.Exports; 6 | 7 | public class Introspection { 8 | 9 | public static void main(String... args) { 10 | Module module = String.class.getModule(); 11 | 12 | String name1 = module.getName(); // Name as defined in module-info.java 13 | System.out.println("Module name: " + name1); 14 | 15 | Set packages1 = module.getPackages(); // Lists all packages in the module 16 | System.out.println("Packages in module: " + packages1); 17 | 18 | // The methods above are convenience methods that return 19 | // information from the Module's ModuleDescriptor: 20 | ModuleDescriptor descriptor = module.getDescriptor(); 21 | String name2 = descriptor.name(); // Same as module.getName(); 22 | System.out.println("Module name from descriptor: " + name2); 23 | 24 | Set packages2 = descriptor.packages(); // Same as module.getPackages(); 25 | System.out.println("Packages from descriptor: " + packages2); 26 | 27 | // Through ModuleDescriptor, all information from module-info.java is exposed: 28 | Set exports = descriptor.exports(); // All exports, possibly qualified 29 | System.out.println("Exports: " + exports); 30 | 31 | Set uses = descriptor.uses(); // All services used by this module 32 | System.out.println("Uses: " + uses); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /chapter6/lookup/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the use of the new VarHandles and MethodHandles that are introduced to replace reflection. -------------------------------------------------------------------------------- /chapter6/lookup/run.sh: -------------------------------------------------------------------------------- 1 | javac --module-source-path src -d out -m ormframework,application 2 | java --module-path out -m application/javamodularity.application.Main 3 | -------------------------------------------------------------------------------- /chapter6/lookup/src/application/javamodularity/application/Book.java: -------------------------------------------------------------------------------- 1 | package javamodularity.application; 2 | 3 | public class Book { 4 | 5 | private String title; 6 | 7 | protected Book() { 8 | 9 | } 10 | 11 | public String getTitle() { 12 | return title; 13 | } 14 | 15 | protected void setTitle(String title) { 16 | this.title = title; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter6/lookup/src/application/javamodularity/application/Main.java: -------------------------------------------------------------------------------- 1 | package javamodularity.application; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | import java.lang.invoke.MethodHandles.Lookup; 5 | 6 | import javamodularity.ormframework.OrmFramework; 7 | 8 | public class Main { 9 | 10 | public static void main(String... args) { 11 | Lookup lookup = MethodHandles.lookup(); 12 | OrmFramework ormFramework = new OrmFramework(lookup); 13 | 14 | Book book = ormFramework.loadfromDatabase("/* query */", Book.class); 15 | 16 | System.out.println(book.getTitle()); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /chapter6/lookup/src/application/module-info.java: -------------------------------------------------------------------------------- 1 | module application { 2 | requires ormframework; 3 | } 4 | -------------------------------------------------------------------------------- /chapter6/lookup/src/ormframework/javamodularity/ormframework/OrmFramework.java: -------------------------------------------------------------------------------- 1 | package javamodularity.ormframework; 2 | 3 | import java.lang.invoke.MethodHandle; 4 | import java.lang.invoke.MethodHandles; 5 | import java.lang.invoke.MethodHandles.Lookup; 6 | import java.lang.invoke.MethodType; 7 | import java.lang.invoke.VarHandle; 8 | 9 | public class OrmFramework { 10 | 11 | private Lookup lookup; 12 | 13 | public OrmFramework(Lookup lookup) { this.lookup = lookup; } 14 | 15 | public T loadfromDatabase(String query, Class clazz) { 16 | try { 17 | MethodHandle ctor = lookup.findConstructor(clazz, MethodType.methodType(void.class)); 18 | T entity = (T) ctor.invoke(); 19 | 20 | Lookup privateLookup = MethodHandles.privateLookupIn​(clazz, lookup); 21 | VarHandle title = privateLookup.findVarHandle(clazz, "title", String.class); // Name/type presumably found in some orm mapping config 22 | title.set(entity, "Loaded from database!"); 23 | return entity; 24 | } catch(Throwable e) { 25 | throw new RuntimeException(e); 26 | } 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /chapter6/lookup/src/ormframework/module-info.java: -------------------------------------------------------------------------------- 1 | module ormframework { 2 | exports javamodularity.ormframework; 3 | } 4 | -------------------------------------------------------------------------------- /chapter6/plugins/README.md: -------------------------------------------------------------------------------- 1 | This example shows a plugin system that loads plugin modules dynamically from directories. -------------------------------------------------------------------------------- /chapter6/plugins/run.sh: -------------------------------------------------------------------------------- 1 | rm -rf out-pluginhost/ out-plugins/ 2 | 3 | # Compile main application + plugin API first 4 | javac --module-source-path src-pluginhost -d out-pluginhost -m pluginhost,pluginhost.api 5 | # Compile plugin a to api of the main application 6 | javac --module-path out-pluginhost/pluginhost.api --module-source-path src-plugina -d out-plugina -m plugin.a 7 | # Compile plugin b to api of the main application 8 | javac --module-path out-pluginhost/pluginhost.api --module-source-path src-pluginb -d out-pluginb -m plugin.b 9 | 10 | # Run the main app, without putting the compiled modules on the module path. 11 | # These are loaded by the application as plugins! 12 | java --module-path out-pluginhost --add-modules ALL-SYSTEM -m pluginhost/pluginhost.PluginHostMain out-plugina out-pluginb 13 | -------------------------------------------------------------------------------- /chapter6/plugins/src-plugina/plugin.a/module-info.java: -------------------------------------------------------------------------------- 1 | module plugin.a { 2 | requires pluginhost.api; 3 | 4 | provides pluginhost.api.Plugin 5 | with plugina.PluginA; 6 | } 7 | -------------------------------------------------------------------------------- /chapter6/plugins/src-plugina/plugin.a/plugina/PluginA.java: -------------------------------------------------------------------------------- 1 | package plugina; 2 | 3 | import pluginhost.api.Plugin; 4 | 5 | public class PluginA implements Plugin { 6 | 7 | public String getName() { 8 | return "Plugin A"; 9 | } 10 | 11 | public void doWork() { 12 | System.out.println("Doing whatever plugins do!"); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /chapter6/plugins/src-pluginb/plugin.b/module-info.java: -------------------------------------------------------------------------------- 1 | module plugin.b { 2 | requires pluginhost.api; 3 | requires somelibrary; 4 | 5 | provides pluginhost.api.Plugin 6 | with pluginb.PluginB; 7 | } 8 | -------------------------------------------------------------------------------- /chapter6/plugins/src-pluginb/plugin.b/pluginb/PluginB.java: -------------------------------------------------------------------------------- 1 | package pluginb; 2 | 3 | import pluginhost.api.Plugin; 4 | 5 | import some.library.Helper; 6 | 7 | public class PluginB implements Plugin { 8 | 9 | public String getName() { 10 | return "Plugin B"; 11 | } 12 | 13 | public void doWork() { 14 | System.out.println("Doing whatever second plugins do: " + Helper.help()); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /chapter6/plugins/src-pluginb/somelibrary/module-info.java: -------------------------------------------------------------------------------- 1 | module somelibrary { 2 | exports some.library; 3 | } 4 | -------------------------------------------------------------------------------- /chapter6/plugins/src-pluginb/somelibrary/some/library/Helper.java: -------------------------------------------------------------------------------- 1 | package some.library; 2 | 3 | public class Helper { 4 | 5 | public static String help() { 6 | return "with some additional help!"; 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /chapter6/plugins/src-pluginhost/pluginhost.api/module-info.java: -------------------------------------------------------------------------------- 1 | module pluginhost.api { 2 | exports pluginhost.api; 3 | } 4 | -------------------------------------------------------------------------------- /chapter6/plugins/src-pluginhost/pluginhost.api/pluginhost/api/Plugin.java: -------------------------------------------------------------------------------- 1 | package pluginhost.api; 2 | 3 | public interface Plugin { 4 | String getName(); 5 | void doWork(); 6 | } 7 | -------------------------------------------------------------------------------- /chapter6/plugins/src-pluginhost/pluginhost/module-info.java: -------------------------------------------------------------------------------- 1 | module pluginhost { 2 | requires pluginhost.api; 3 | 4 | uses pluginhost.api.Plugin; 5 | } 6 | -------------------------------------------------------------------------------- /chapter7/encapsulation/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the error shown when compiling against a now encapsulated type, even when running on the classpath. -------------------------------------------------------------------------------- /chapter7/encapsulation/run.sh: -------------------------------------------------------------------------------- 1 | mkdir -p mods 2 | 3 | $JAVA_HOME/bin/javac -d out -sourcepath src $(find src -name '*.java') 4 | -------------------------------------------------------------------------------- /chapter7/encapsulation/src/encapsulated/EncapsulatedTypes.java: -------------------------------------------------------------------------------- 1 | package encapsulated; 2 | 3 | import sun.security.x509.X500Name; 4 | 5 | public class EncapsulatedTypes { 6 | public static void main(String... args) throws Exception { 7 | System.out.println(new X500Name("test.com", "test", 8 | "test", "US")); 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /chapter7/jaxb/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates how to use JAXB by using --add-modules explicitly when compiling and running on the classpath. -------------------------------------------------------------------------------- /chapter7/jaxb/run.sh: -------------------------------------------------------------------------------- 1 | $JAVA_HOME/bin/javac -d out --add-modules java.xml.bind -sourcepath src $(find src -name '*.java') 2 | $JAVA_HOME/bin/java -cp out --add-modules java.xml.bind example.JaxbExample -------------------------------------------------------------------------------- /chapter7/jaxb/src/example/Book.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | import javax.xml.bind.annotation.XmlAttribute; 4 | import javax.xml.bind.annotation.XmlElement; 5 | import javax.xml.bind.annotation.XmlRootElement; 6 | 7 | 8 | @XmlRootElement 9 | public class Book { 10 | private String title; 11 | 12 | public String getTitle() { 13 | return title; 14 | } 15 | 16 | @XmlElement 17 | public void setTitle(String title) { 18 | this.title = title; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /chapter7/jaxb/src/example/JaxbExample.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | import javax.xml.bind.JAXBContext; 4 | import javax.xml.bind.JAXBException; 5 | import javax.xml.bind.Marshaller; 6 | 7 | public class JaxbExample { 8 | public static void main(String... args) throws Exception { 9 | Book book = new Book(); 10 | book.setTitle("Java 9 Modularity"); 11 | 12 | JAXBContext jaxbContext = JAXBContext.newInstance(Book.class); 13 | Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 14 | 15 | jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 16 | 17 | jaxbMarshaller.marshal(book, System.out); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chapter7/removedtypes/README.md: -------------------------------------------------------------------------------- 1 | This example shows the error that occurs when compiling against a removed type such as `sun.misc.BASE64Decoder`. -------------------------------------------------------------------------------- /chapter7/removedtypes/run.sh: -------------------------------------------------------------------------------- 1 | $JAVA_HOME/bin/javac -d out -sourcepath src $(find src -name '*.java') 2 | -------------------------------------------------------------------------------- /chapter7/removedtypes/src/removed/RemovedTypes.java: -------------------------------------------------------------------------------- 1 | package removed; 2 | 3 | import sun.misc.BASE64Decoder; 4 | 5 | // Compile with Java 8, run on Java 9: NoClassDefFoundError. 6 | public class RemovedTypes { 7 | public static void main(String... args) throws Exception { 8 | new BASE64Decoder(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /chapter8/jackson-classpath/README.md: -------------------------------------------------------------------------------- 1 | This is the code for the Jackson example before migration, where the code still lives on the classpath. -------------------------------------------------------------------------------- /chapter8/jackson-classpath/lib/jackson-annotations-2.8.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter8/jackson-classpath/lib/jackson-annotations-2.8.8.jar -------------------------------------------------------------------------------- /chapter8/jackson-classpath/lib/jackson-core-2.8.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter8/jackson-classpath/lib/jackson-core-2.8.8.jar -------------------------------------------------------------------------------- /chapter8/jackson-classpath/lib/jackson-databind-2.8.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter8/jackson-classpath/lib/jackson-databind-2.8.8.jar -------------------------------------------------------------------------------- /chapter8/jackson-classpath/run.sh: -------------------------------------------------------------------------------- 1 | CP=lib/jackson-annotations-2.8.8.jar: 2 | CP+=lib/jackson-core-2.8.8.jar: 3 | CP+=lib/jackson-databind-2.8.8.jar 4 | 5 | javac -cp $CP -d out -sourcepath src $(find src -name '*.java') 6 | 7 | java -cp $CP:out demo.Main 8 | -------------------------------------------------------------------------------- /chapter8/jackson-classpath/src/demo/Book.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | public class Book { 4 | private String title; 5 | private String description; 6 | 7 | public Book(String title, String description) { 8 | this.title = title; 9 | this.description = description; 10 | } 11 | 12 | public String getTitle() { 13 | return title; 14 | } 15 | 16 | public String getDescription() { 17 | return description; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chapter8/jackson-classpath/src/demo/Main.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | public class Main { 6 | 7 | public static void main(String... args) throws Exception { 8 | Book modularityBook = 9 | new Book("Java 9 Modularity", "Modularize all the things!"); 10 | 11 | ObjectMapper mapper = new ObjectMapper(); 12 | String json = mapper.writeValueAsString(modularityBook); 13 | System.out.println(json); 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter8/jackson/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the use of automatic modules. -------------------------------------------------------------------------------- /chapter8/jackson/lib/jackson-annotations-2.8.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter8/jackson/lib/jackson-annotations-2.8.8.jar -------------------------------------------------------------------------------- /chapter8/jackson/lib/jackson-core-2.8.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter8/jackson/lib/jackson-core-2.8.8.jar -------------------------------------------------------------------------------- /chapter8/jackson/mods/jackson-databind-2.8.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter8/jackson/mods/jackson-databind-2.8.8.jar -------------------------------------------------------------------------------- /chapter8/jackson/run.sh: -------------------------------------------------------------------------------- 1 | CP=lib/jackson-annotations-2.8.8.jar: 2 | CP+=lib/jackson-core-2.8.8.jar 3 | 4 | $JAVA_HOME/bin/javac -cp $CP --module-path mods -d out --module-source-path src -m books 5 | 6 | $JAVA_HOME/bin/java -cp $CP --module-path mods:out -m books/demo.Main 7 | -------------------------------------------------------------------------------- /chapter8/jackson/src/books/demo/Book.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | public class Book { 4 | private String title; 5 | private String description; 6 | 7 | public Book(String title, String description) { 8 | this.title = title; 9 | this.description = description; 10 | } 11 | 12 | public String getTitle() { 13 | return title; 14 | } 15 | 16 | public String getDescription() { 17 | return description; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chapter8/jackson/src/books/demo/Main.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | public class Main { 6 | 7 | public static void main(String... args) throws Exception { 8 | Book modularityBook = 9 | new Book("Java 9 Modularity", "Modularize all the things!"); 10 | 11 | ObjectMapper mapper = new ObjectMapper(); 12 | String json = mapper.writeValueAsString(modularityBook); 13 | System.out.println(json); 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter8/jackson/src/books/module-info.java: -------------------------------------------------------------------------------- 1 | module books { 2 | requires jackson.databind; 3 | opens demo; 4 | } 5 | -------------------------------------------------------------------------------- /chapter8/readability_rules/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates the error that happens when a type is used from a transitive dependency of a automatic module, while that dependency is still on the classpath. -------------------------------------------------------------------------------- /chapter8/readability_rules/jars/jackson-annotations-2.8.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter8/readability_rules/jars/jackson-annotations-2.8.8.jar -------------------------------------------------------------------------------- /chapter8/readability_rules/jars/jackson-core-2.8.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter8/readability_rules/jars/jackson-core-2.8.8.jar -------------------------------------------------------------------------------- /chapter8/readability_rules/mods/jackson-databind-2.8.8.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter8/readability_rules/mods/jackson-databind-2.8.8.1.jar -------------------------------------------------------------------------------- /chapter8/readability_rules/run.sh: -------------------------------------------------------------------------------- 1 | CP=lib/jackson-annotations-2.8.8.jar: 2 | CP+=lib/jackson-core-2.8.8.jar 3 | 4 | $JAVA_HOME/bin/javac --module-path mods \ 5 | -cp $CP \ 6 | -d out \ 7 | --module-source-path src \ 8 | -m books 9 | -------------------------------------------------------------------------------- /chapter8/readability_rules/src/books/demo/Book.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | public class Book { 4 | private String title; 5 | private String description; 6 | 7 | public Book(String title, String description) { 8 | this.title = title; 9 | this.description = description; 10 | } 11 | 12 | public String getTitle() { 13 | return title; 14 | } 15 | 16 | public String getDescription() { 17 | return description; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chapter8/readability_rules/src/books/demo/Main.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.core.Versioned; 5 | 6 | public class Main { 7 | 8 | public static void main(String... args) throws Exception { 9 | Book modularityBook = 10 | new Book("Java 9 Modularity", "Modularize all the things!"); 11 | 12 | ObjectMapper mapper = new ObjectMapper(); 13 | String json = mapper.writeValueAsString(modularityBook); 14 | System.out.println(json); 15 | 16 | Versioned versioned = (Versioned) mapper; 17 | System.out.println(versioned.version()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /chapter8/readability_rules/src/books/module-info.java: -------------------------------------------------------------------------------- 1 | module books { 2 | requires jackson.databind; 3 | opens demo; 4 | } 5 | -------------------------------------------------------------------------------- /chapter8/runtime_loading/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates dynamically loading a JDBC driver. 2 | Note that it is required to explicitly require `java.sql`, because this is a dependency of the JDBC driver. -------------------------------------------------------------------------------- /chapter8/runtime_loading/mods/hsqldb.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter8/runtime_loading/mods/hsqldb.jar -------------------------------------------------------------------------------- /chapter8/runtime_loading/run.sh: -------------------------------------------------------------------------------- 1 | $JAVA_HOME/bin/javac --module-path mods \ 2 | -d out \ 3 | --module-source-path src \ 4 | -m runtime.loading.example 5 | $JAVA_HOME/bin/java --module-path mods:out --add-modules hsqldb -m runtime.loading.example/demo.Main 6 | -------------------------------------------------------------------------------- /chapter8/runtime_loading/src/runtime.loading.example/demo/Main.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | public class Main { 4 | 5 | public static void main(String... args) throws Exception { 6 | Class clazz = Class.forName("org.hsqldb.jdbcDriver"); 7 | System.out.println(clazz.getName()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /chapter8/runtime_loading/src/runtime.loading.example/module-info.java: -------------------------------------------------------------------------------- 1 | module runtime.loading.example { 2 | requires java.sql; 3 | } 4 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/.gitignore -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/README.md: -------------------------------------------------------------------------------- 1 | This example is the Spring/Hibernate application after splitting the code into multiple modules. -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/antlr-2.7.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/antlr-2.7.7.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/cdi-api-1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/cdi-api-1.1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/classmate-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/classmate-1.3.0.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/commons-dbcp-1.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/commons-dbcp-1.4.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/commons-logging-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/commons-logging-1.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/commons-pool-1.5.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/commons-pool-1.5.4.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/dom4j-1.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/dom4j-1.6.1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/el-api-2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/el-api-2.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/geronimo-jta_1.1_spec-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/geronimo-jta_1.1_spec-1.1.1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/hibernate-commons-annotations-5.0.1.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/hibernate-commons-annotations-5.0.1.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/hsqldb-2.3.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/hsqldb-2.3.4.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/jandex-2.0.0.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/jandex-2.0.0.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/jboss-logging-3.3.0.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/jboss-logging-3.3.0.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/jcl-over-slf4j-1.7.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/jcl-over-slf4j-1.7.21.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/jsr250-api-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/jsr250-api-1.0.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/log4j-api-2.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/log4j-api-2.6.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/log4j-core-2.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/log4j-core-2.6.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/slf4j-api-1.7.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/slf4j-api-1.7.21.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/slf4j-simple-1.7.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/slf4j-simple-1.7.21.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/spring-aop-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/spring-aop-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/spring-beans-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/spring-beans-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/spring-core-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/spring-core-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/spring-expression-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/spring-expression-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/spring-jdbc-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/spring-jdbc-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/lib/spring-orm-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/lib/spring-orm-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/mods/books.api@1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/mods/books.api@1.0.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/mods/books.impl@1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/mods/books.impl@1.0.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/mods/bookstore@1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/mods/bookstore@1.0.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/mods/hibernate-core-5.2.2.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/mods/hibernate-core-5.2.2.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/mods/hibernate-jpa-2.1-api-1.0.0.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/mods/hibernate-jpa-2.1-api-1.0.0.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/mods/javassist-3.20.0-GA.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/mods/javassist-3.20.0-GA.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/mods/javax.inject-1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/mods/javax.inject-1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/mods/main@1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/mods/main@1.0.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/mods/spring-context-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/mods/spring-context-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/mods/spring-tx-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-refactored/mods/spring-tx-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/run.sh: -------------------------------------------------------------------------------- 1 | CLASSPATH=lib/antlr-2.7.7.jar:lib/cdi-api-1.1.jar:lib/classmate-1.3.0.jar:lib/commons-dbcp-1.4.jar:lib/commons-logging-1.2.jar:lib/commons-pool-1.5.4.jar:lib/dom4j-1.6.1.jar:lib/el-api-2.2.jar:lib/geronimo-jta_1.1_spec-1.1.1.jar:lib/hibernate-commons-annotations-5.0.1.Final.jar:lib/hsqldb-2.3.4.jar:lib/jandex-2.0.0.Final.jar:lib/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar:lib/jboss-logging-3.3.0.Final.jar:lib/jcl-over-slf4j-1.7.21.jar:lib/jsr250-api-1.0.jar:lib/log4j-api-2.6.2.jar:lib/log4j-core-2.6.2.jar:lib/slf4j-api-1.7.21.jar:lib/slf4j-simple-1.7.21.jar:lib/spring-aop-4.3.2.RELEASE.jar:lib/spring-beans-4.3.2.RELEASE.jar:lib/spring-core-4.3.2.RELEASE.jar:lib/spring-expression-4.3.2.RELEASE.jar:lib/spring-jdbc-4.3.2.RELEASE.jar:lib/spring-orm-4.3.2.RELEASE.jar 2 | 3 | javac -cp $CLASSPATH \ 4 | --module-path mods \ 5 | -d out \ 6 | --module-source-path src \ 7 | -m books.api,books.impl,bookstore,main 8 | 9 | cp $(find src -name '*.xml') out/main 10 | 11 | java -cp $CLASSPATH \ 12 | --module-path mods:out \ 13 | --add-modules java.xml.bind,java.sql,books.impl \ 14 | --add-opens java.base/java.lang=javassist \ 15 | -m main/main.Main 16 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/books.api/books/api/entities/Book.java: -------------------------------------------------------------------------------- 1 | package books.api.entities; 2 | 3 | public interface Book { 4 | int getId(); 5 | String getTitle(); 6 | double getPrice(); 7 | } 8 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/books.api/books/api/service/BooksService.java: -------------------------------------------------------------------------------- 1 | package books.api.service; 2 | 3 | import books.api.entities.Book; 4 | 5 | public interface BooksService { 6 | Book getBook(int id); 7 | int createBook(String title, double price); 8 | } 9 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/books.api/module-info.java: -------------------------------------------------------------------------------- 1 | module books.api { 2 | exports books.api.entities; 3 | exports books.api.service; 4 | } -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/books.impl/books/impl/entities/BookEntity.java: -------------------------------------------------------------------------------- 1 | package books.impl.entities; 2 | 3 | import books.api.entities.Book; 4 | import javax.persistence.*; 5 | 6 | @Entity 7 | public class BookEntity implements Book { 8 | @Id @GeneratedValue 9 | private int id; 10 | private String title; 11 | private double price; 12 | 13 | public BookEntity() {} 14 | 15 | public BookEntity(String title, double price) { 16 | this.title = title; 17 | this.price = price; 18 | } 19 | 20 | public int getId() { 21 | return id; 22 | } 23 | 24 | public String getTitle() { 25 | return title; 26 | } 27 | 28 | public double getPrice() { 29 | return price; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/books.impl/books/impl/service/HibernateBooksService.java: -------------------------------------------------------------------------------- 1 | package books.impl.service; 2 | 3 | import books.api.entities.Book; 4 | import books.api.service.BooksService; 5 | import books.impl.entities.BookEntity; 6 | import org.springframework.transaction.annotation.Transactional; 7 | import org.springframework.stereotype.Repository; 8 | import org.hibernate.SessionFactory; 9 | import javax.inject.Inject; 10 | 11 | @Repository 12 | @Transactional 13 | public class HibernateBooksService implements BooksService { 14 | 15 | @Inject 16 | private SessionFactory sessionFactory; 17 | 18 | public Book getBook(int id) { 19 | return sessionFactory.getCurrentSession().get(BookEntity.class, id); 20 | } 21 | 22 | public int createBook(String title, double price) { 23 | 24 | BookEntity entity = new BookEntity(title, price); 25 | sessionFactory.getCurrentSession().saveOrUpdate(entity); 26 | 27 | return entity.getId(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/books.impl/module-info.java: -------------------------------------------------------------------------------- 1 | module books.impl { 2 | requires books.api; 3 | 4 | requires java.naming; 5 | requires spring.tx; 6 | requires javax.inject; 7 | requires hibernate.core; 8 | requires hibernate.jpa; 9 | 10 | opens books.impl.entities; 11 | opens books.impl.service; 12 | } -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/bookstore/bookstore-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/bookstore/bookstore/api/service/BookstoreService.java: -------------------------------------------------------------------------------- 1 | package bookstore.api.service; 2 | 3 | import books.api.service.BooksService; 4 | 5 | public interface BookstoreService { 6 | double calculatePrice(int... bookIds); 7 | } 8 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/bookstore/bookstore/impl/service/BookstoreServiceImpl.java: -------------------------------------------------------------------------------- 1 | package bookstore.impl.service; 2 | 3 | import java.util.Arrays; 4 | import books.api.entities.Book; 5 | import books.api.service.BooksService; 6 | import bookstore.api.service.BookstoreService; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class BookstoreServiceImpl implements BookstoreService { 11 | 12 | private static double TAX = 1.21d; 13 | 14 | private BooksService booksService; 15 | 16 | public BookstoreServiceImpl(BooksService booksService) { 17 | this.booksService = booksService; 18 | } 19 | 20 | public double calculatePrice(int... bookIds) { 21 | double total = Arrays 22 | .stream(bookIds) 23 | .mapToDouble(id -> booksService.getBook(id).getPrice()) 24 | .sum(); 25 | 26 | return total * TAX; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/bookstore/module-info.java: -------------------------------------------------------------------------------- 1 | module bookstore { 2 | requires books.api; 3 | 4 | requires spring.context; 5 | 6 | exports bookstore.api.service; 7 | opens bookstore.impl.service; 8 | } -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/main/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/main/main/Main.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.context.support.ClassPathXmlApplicationContext; 5 | import books.api.service.BooksService; 6 | import books.api.entities.Book; 7 | import bookstore.api.service.BookstoreService; 8 | 9 | public class Main { 10 | 11 | public void start() { 12 | System.out.println("Starting..."); 13 | 14 | ApplicationContext context = 15 | new ClassPathXmlApplicationContext(new String[] {"classpath:/bookstore-spring.xml","classpath:/books-spring.xml"}); 16 | 17 | 18 | BooksService booksService = context.getBean(BooksService.class); 19 | BookstoreService store = context.getBean(BookstoreService.class); 20 | 21 | // Create some books 22 | int id1 = booksService.createBook("Java 9 Modularity", 45.0d); 23 | int id2 = booksService.createBook("Modular Cloud Apps with OSGi", 40.0d); 24 | printf("Created books with id [%d, %d]", id1, id2); 25 | 26 | // Retrieve them again 27 | Book book1 = booksService.getBook(id1); 28 | Book book2 = booksService.getBook(id2); 29 | printf("Retrieved books:\n %d: %s [%.2f]\n %d: %s [%.2f]", 30 | id1, book1.getTitle(), book1.getPrice(), id2, book2.getTitle(), book2.getPrice()); 31 | 32 | // Use the other service to calculate a total 33 | double total = store.calculatePrice(id1, id2); 34 | printf("Total price (with tax): %.2f", total); 35 | 36 | } 37 | 38 | public static void main(String[] args) { 39 | new Main().start(); 40 | } 41 | 42 | private void printf(String msg, Object... args) { 43 | System.out.println(String.format(msg + "\n", args)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-refactored/src/main/module-info.java: -------------------------------------------------------------------------------- 1 | module main { 2 | requires spring.context; 3 | requires books.api; 4 | requires bookstore; 5 | } -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/README.md: -------------------------------------------------------------------------------- 1 | This example is the Spring/Hibernate application before migration. All code and dependnecies are still on the classpath. 2 | Use this example as a starting point if you want to follow along with the migration case study in the book. -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/antlr-2.7.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/antlr-2.7.7.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/cdi-api-1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/cdi-api-1.1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/classmate-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/classmate-1.3.0.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/commons-dbcp-1.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/commons-dbcp-1.4.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/commons-logging-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/commons-logging-1.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/commons-pool-1.5.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/commons-pool-1.5.4.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/dom4j-1.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/dom4j-1.6.1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/el-api-2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/el-api-2.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/geronimo-jta_1.1_spec-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/geronimo-jta_1.1_spec-1.1.1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/hibernate-commons-annotations-5.0.1.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/hibernate-commons-annotations-5.0.1.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/hibernate-core-5.2.2.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/hibernate-core-5.2.2.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/hibernate-jpa-2.1-api-1.0.0.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/hibernate-jpa-2.1-api-1.0.0.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/hsqldb-2.3.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/hsqldb-2.3.4.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/jandex-2.0.0.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/jandex-2.0.0.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/javassist-3.20.0-GA.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/javassist-3.20.0-GA.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/javax.inject-1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/javax.inject-1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/jboss-logging-3.3.0.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/jboss-logging-3.3.0.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/jcl-over-slf4j-1.7.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/jcl-over-slf4j-1.7.21.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/jsr250-api-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/jsr250-api-1.0.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/log4j-api-2.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/log4j-api-2.6.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/log4j-core-2.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/log4j-core-2.6.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/slf4j-api-1.7.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/slf4j-api-1.7.21.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/slf4j-simple-1.7.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/slf4j-simple-1.7.21.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/spring-aop-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/spring-aop-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/spring-beans-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/spring-beans-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/spring-context-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/spring-context-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/spring-core-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/spring-core-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/spring-expression-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/spring-expression-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/spring-jdbc-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/spring-jdbc-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/spring-orm-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/spring-orm-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/lib/spring-tx-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate-starter/lib/spring-tx-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/run.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | CLASSPATH=lib/antlr-2.7.7.jar:lib/cdi-api-1.1.jar:lib/classmate-1.3.0.jar:lib/commons-dbcp-1.4.jar:lib/commons-logging-1.2.jar:lib/commons-pool-1.5.4.jar:lib/dom4j-1.6.1.jar:lib/el-api-2.2.jar:lib/geronimo-jta_1.1_spec-1.1.1.jar:lib/hibernate-commons-annotations-5.0.1.Final.jar:lib/hibernate-core-5.2.2.Final.jar:lib/hibernate-jpa-2.1-api-1.0.0.Final.jar:lib/hsqldb-2.3.4.jar:lib/jandex-2.0.0.Final.jar:lib/javassist-3.20.0-GA.jar:lib/javax.inject-1.jar:lib/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar:lib/jboss-logging-3.3.0.Final.jar:lib/jcl-over-slf4j-1.7.21.jar:lib/jsr250-api-1.0.jar:lib/log4j-api-2.6.2.jar:lib/log4j-core-2.6.2.jar:lib/slf4j-api-1.7.21.jar:lib/slf4j-simple-1.7.21.jar:lib/spring-aop-4.3.2.RELEASE.jar:lib/spring-beans-4.3.2.RELEASE.jar:lib/spring-context-4.3.2.RELEASE.jar:lib/spring-core-4.3.2.RELEASE.jar:lib/spring-expression-4.3.2.RELEASE.jar:lib/spring-jdbc-4.3.2.RELEASE.jar:lib/spring-orm-4.3.2.RELEASE.jar:lib/spring-tx-4.3.2.RELEASE.jar 3 | 4 | $JAVA_HOME/bin/javac -cp $CLASSPATH -d out -sourcepath src $(find src -name '*.java') 5 | 6 | cp $(find src -name '*.xml') out 7 | 8 | $JAVA_HOME/bin/java -cp $CLASSPATH:out main.Main 9 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/src/books/api/entities/Book.java: -------------------------------------------------------------------------------- 1 | package books.api.entities; 2 | 3 | public interface Book { 4 | int getId(); 5 | String getTitle(); 6 | double getPrice(); 7 | } 8 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/src/books/api/service/BooksService.java: -------------------------------------------------------------------------------- 1 | package books.api.service; 2 | 3 | import books.api.entities.Book; 4 | 5 | public interface BooksService { 6 | Book getBook(int id); 7 | int createBook(String title, double price); 8 | } 9 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/src/books/impl/entities/BookEntity.java: -------------------------------------------------------------------------------- 1 | package books.impl.entities; 2 | 3 | import books.api.entities.Book; 4 | import javax.persistence.*; 5 | 6 | @Entity 7 | public class BookEntity implements Book { 8 | @Id @GeneratedValue 9 | private int id; 10 | private String title; 11 | private double price; 12 | 13 | public BookEntity() {} 14 | 15 | public BookEntity(String title, double price) { 16 | this.title = title; 17 | this.price = price; 18 | } 19 | 20 | public int getId() { 21 | return id; 22 | } 23 | 24 | public String getTitle() { 25 | return title; 26 | } 27 | 28 | public double getPrice() { 29 | return price; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/src/books/impl/service/HibernateBooksService.java: -------------------------------------------------------------------------------- 1 | package books.impl.service; 2 | 3 | import books.api.entities.Book; 4 | import books.api.service.BooksService; 5 | import books.impl.entities.BookEntity; 6 | import org.springframework.transaction.annotation.Transactional; 7 | import org.springframework.stereotype.Repository; 8 | import org.hibernate.SessionFactory; 9 | import javax.inject.Inject; 10 | 11 | @Repository 12 | @Transactional 13 | public class HibernateBooksService implements BooksService { 14 | 15 | @Inject 16 | private SessionFactory sessionFactory; 17 | 18 | public Book getBook(int id) { 19 | return sessionFactory.getCurrentSession().get(BookEntity.class, id); 20 | } 21 | 22 | public int createBook(String title, double price) { 23 | 24 | BookEntity entity = new BookEntity(title, price); 25 | sessionFactory.getCurrentSession().saveOrUpdate(entity); 26 | 27 | return entity.getId(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/src/bookstore/api/service/BookstoreService.java: -------------------------------------------------------------------------------- 1 | package bookstore.api.service; 2 | 3 | import books.api.service.BooksService; 4 | 5 | public interface BookstoreService { 6 | double calculatePrice(int... bookIds); 7 | } 8 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/src/bookstore/impl/service/BookstoreServiceImpl.java: -------------------------------------------------------------------------------- 1 | package bookstore.impl.service; 2 | 3 | import java.util.Arrays; 4 | import books.api.entities.Book; 5 | import books.api.service.BooksService; 6 | import bookstore.api.service.BookstoreService; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class BookstoreServiceImpl implements BookstoreService { 11 | 12 | private static double TAX = 1.21d; 13 | 14 | private BooksService booksService; 15 | 16 | public BookstoreServiceImpl(BooksService booksService) { 17 | this.booksService = booksService; 18 | } 19 | 20 | public double calculatePrice(int... bookIds) { 21 | double total = Arrays 22 | .stream(bookIds) 23 | .mapToDouble(id -> booksService.getBook(id).getPrice()) 24 | .sum(); 25 | 26 | return total * TAX; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/src/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate-starter/src/main/Main.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.context.support.ClassPathXmlApplicationContext; 5 | import books.api.service.BooksService; 6 | import books.api.entities.Book; 7 | import bookstore.api.service.BookstoreService; 8 | 9 | public class Main { 10 | 11 | public void start() { 12 | System.out.println("Starting..."); 13 | 14 | ApplicationContext context = 15 | new ClassPathXmlApplicationContext(new String[] {"classpath:/main.xml"}); 16 | 17 | 18 | BooksService booksService = context.getBean(BooksService.class); 19 | BookstoreService store = context.getBean(BookstoreService.class); 20 | 21 | // Create some books 22 | int id1 = booksService.createBook("Java 9 Modularity", 45.0d); 23 | int id2 = booksService.createBook("Modular Cloud Apps with OSGi", 40.0d); 24 | printf("Created books with id [%d, %d]", id1, id2); 25 | 26 | // Retrieve them again 27 | Book book1 = booksService.getBook(id1); 28 | Book book2 = booksService.getBook(id2); 29 | printf("Retrieved books:\n %d: %s [%.2f]\n %d: %s [%.2f]", 30 | id1, book1.getTitle(), book1.getPrice(), id2, book2.getTitle(), book2.getPrice()); 31 | 32 | // Use the other service to calculate a total 33 | double total = store.calculatePrice(id1, id2); 34 | printf("Total price (with tax): %.2f", total); 35 | 36 | } 37 | 38 | public static void main(String[] args) { 39 | new Main().start(); 40 | } 41 | 42 | private void printf(String msg, Object... args) { 43 | System.out.println(String.format(msg + "\n", args)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate/README.md: -------------------------------------------------------------------------------- 1 | This example is the Spring/Hibernate application after migrating to a single module. -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/antlr-2.7.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/antlr-2.7.7.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/cdi-api-1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/cdi-api-1.1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/classmate-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/classmate-1.3.0.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/commons-dbcp-1.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/commons-dbcp-1.4.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/commons-logging-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/commons-logging-1.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/commons-pool-1.5.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/commons-pool-1.5.4.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/dom4j-1.6.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/dom4j-1.6.1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/el-api-2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/el-api-2.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/geronimo-jta_1.1_spec-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/geronimo-jta_1.1_spec-1.1.1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/hibernate-commons-annotations-5.0.1.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/hibernate-commons-annotations-5.0.1.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/hsqldb-2.3.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/hsqldb-2.3.4.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/jandex-2.0.0.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/jandex-2.0.0.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/jboss-logging-3.3.0.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/jboss-logging-3.3.0.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/jcl-over-slf4j-1.7.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/jcl-over-slf4j-1.7.21.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/jsr250-api-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/jsr250-api-1.0.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/log4j-api-2.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/log4j-api-2.6.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/log4j-core-2.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/log4j-core-2.6.2.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/slf4j-api-1.7.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/slf4j-api-1.7.21.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/slf4j-simple-1.7.21.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/slf4j-simple-1.7.21.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/spring-aop-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/spring-aop-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/spring-beans-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/spring-beans-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/spring-core-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/spring-core-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/spring-expression-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/spring-expression-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/spring-jdbc-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/spring-jdbc-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/lib/spring-orm-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/lib/spring-orm-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/mods/hibernate-core-5.2.2.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/mods/hibernate-core-5.2.2.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/mods/hibernate-jpa-2.1-api-1.0.0.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/mods/hibernate-jpa-2.1-api-1.0.0.Final.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/mods/javassist-3.20.0-GA.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/mods/javassist-3.20.0-GA.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/mods/javax.inject-1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/mods/javax.inject-1.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/mods/spring-context-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/mods/spring-context-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/mods/spring-tx-4.3.2.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/chapter9/spring-hibernate/mods/spring-tx-4.3.2.RELEASE.jar -------------------------------------------------------------------------------- /chapter9/spring-hibernate/run.sh: -------------------------------------------------------------------------------- 1 | CP=lib/antlr-2.7.7.jar: 2 | CP+=lib/cdi-api-1.1.jar: 3 | CP+=lib/classmate-1.3.0.jar: 4 | CP+=lib/commons-dbcp-1.4.jar: 5 | CP+=lib/commons-logging-1.2.jar: 6 | CP+=lib/commons-pool-1.5.4.jar: 7 | CP+=lib/dom4j-1.6.1.jar: 8 | CP+=lib/el-api-2.2.jar: 9 | CP+=lib/geronimo-jta_1.1_spec-1.1.1.jar: 10 | CP+=lib/hibernate-commons-annotations-5.0.1.Final.jar: 11 | CP+=lib/hsqldb-2.3.4.jar: 12 | CP+=lib/jandex-2.0.0.Final.jar: 13 | CP+=lib/jboss-interceptors-api_1.1_spec-1.0.0.Beta1.jar: 14 | CP+=lib/jboss-logging-3.3.0.Final.jar: 15 | CP+=lib/jcl-over-slf4j-1.7.21.jar: 16 | CP+=lib/jsr250-api-1.0.jar: 17 | CP+=lib/log4j-api-2.6.2.jar: 18 | CP+=lib/log4j-core-2.6.2.jar: 19 | CP+=lib/slf4j-api-1.7.21.jar: 20 | CP+=lib/slf4j-simple-1.7.21.jar: 21 | CP+=lib/spring-aop-4.3.2.RELEASE.jar: 22 | CP+=lib/spring-beans-4.3.2.RELEASE.jar: 23 | CP+=lib/spring-core-4.3.2.RELEASE.jar: 24 | CP+=lib/spring-expression-4.3.2.RELEASE.jar: 25 | CP+=lib/spring-jdbc-4.3.2.RELEASE.jar: 26 | CP+=lib/spring-orm-4.3.2.RELEASE.jar 27 | 28 | $JAVA_HOME/bin/javac -cp $CP \ 29 | --module-path mods \ 30 | --add-modules java.naming \ 31 | -d out \ 32 | --module-source-path src \ 33 | -m bookapp 34 | 35 | cp $(find src -name '*.xml') out/bookapp 36 | 37 | $JAVA_HOME/bin/java -cp $CP \ 38 | --module-path mods:out \ 39 | --add-modules java.xml.bind,java.sql \ 40 | --add-opens java.base/java.lang=javassist \ 41 | -m bookapp/main.Main 42 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate/src/bookapp/books/api/entities/Book.java: -------------------------------------------------------------------------------- 1 | package books.api.entities; 2 | 3 | public interface Book { 4 | int getId(); 5 | String getTitle(); 6 | double getPrice(); 7 | } 8 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate/src/bookapp/books/api/service/BooksService.java: -------------------------------------------------------------------------------- 1 | package books.api.service; 2 | 3 | import books.api.entities.Book; 4 | 5 | public interface BooksService { 6 | Book getBook(int id); 7 | int createBook(String title, double price); 8 | } 9 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate/src/bookapp/books/impl/entities/BookEntity.java: -------------------------------------------------------------------------------- 1 | package books.impl.entities; 2 | 3 | import books.api.entities.Book; 4 | import javax.persistence.*; 5 | 6 | @Entity 7 | public class BookEntity implements Book { 8 | @Id @GeneratedValue 9 | private int id; 10 | private String title; 11 | private double price; 12 | 13 | public BookEntity() {} 14 | 15 | public BookEntity(String title, double price) { 16 | this.title = title; 17 | this.price = price; 18 | } 19 | 20 | public int getId() { 21 | return id; 22 | } 23 | 24 | public String getTitle() { 25 | return title; 26 | } 27 | 28 | public double getPrice() { 29 | return price; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate/src/bookapp/books/impl/service/HibernateBooksService.java: -------------------------------------------------------------------------------- 1 | package books.impl.service; 2 | 3 | import books.api.entities.Book; 4 | import books.api.service.BooksService; 5 | import books.impl.entities.BookEntity; 6 | import org.springframework.transaction.annotation.Transactional; 7 | import org.springframework.stereotype.Repository; 8 | import org.hibernate.SessionFactory; 9 | import javax.inject.Inject; 10 | 11 | @Repository 12 | @Transactional 13 | public class HibernateBooksService implements BooksService { 14 | 15 | @Inject 16 | private SessionFactory sessionFactory; 17 | 18 | public Book getBook(int id) { 19 | return sessionFactory.getCurrentSession().get(BookEntity.class, id); 20 | } 21 | 22 | public int createBook(String title, double price) { 23 | 24 | BookEntity entity = new BookEntity(title, price); 25 | sessionFactory.getCurrentSession().saveOrUpdate(entity); 26 | 27 | return entity.getId(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate/src/bookapp/bookstore/api/service/BookstoreService.java: -------------------------------------------------------------------------------- 1 | package bookstore.api.service; 2 | 3 | import books.api.service.BooksService; 4 | 5 | public interface BookstoreService { 6 | double calculatePrice(int... bookIds); 7 | } 8 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate/src/bookapp/bookstore/impl/service/BookstoreServiceImpl.java: -------------------------------------------------------------------------------- 1 | package bookstore.impl.service; 2 | 3 | import java.util.Arrays; 4 | import books.api.entities.Book; 5 | import books.api.service.BooksService; 6 | import bookstore.api.service.BookstoreService; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class BookstoreServiceImpl implements BookstoreService { 11 | 12 | private static double TAX = 1.21d; 13 | 14 | private BooksService booksService; 15 | 16 | public BookstoreServiceImpl(BooksService booksService) { 17 | this.booksService = booksService; 18 | } 19 | 20 | public double calculatePrice(int... bookIds) { 21 | double total = Arrays 22 | .stream(bookIds) 23 | .mapToDouble(id -> booksService.getBook(id).getPrice()) 24 | .sum(); 25 | 26 | return total * TAX; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate/src/bookapp/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate/src/bookapp/main/Main.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.context.support.ClassPathXmlApplicationContext; 5 | import books.api.service.BooksService; 6 | import books.api.entities.Book; 7 | import bookstore.api.service.BookstoreService; 8 | 9 | public class Main { 10 | 11 | public void start() { 12 | System.out.println("Starting..."); 13 | 14 | ApplicationContext context = 15 | new ClassPathXmlApplicationContext(new String[] {"classpath:/main.xml"}); 16 | 17 | 18 | BooksService booksService = context.getBean(BooksService.class); 19 | BookstoreService store = context.getBean(BookstoreService.class); 20 | 21 | // Create some books 22 | int id1 = booksService.createBook("Java 9 Modularity", 45.0d); 23 | int id2 = booksService.createBook("Modular Cloud Apps with OSGi", 40.0d); 24 | printf("Created books with id [%d, %d]", id1, id2); 25 | 26 | // Retrieve them again 27 | Book book1 = booksService.getBook(id1); 28 | Book book2 = booksService.getBook(id2); 29 | printf("Retrieved books:\n %d: %s [%.2f]\n %d: %s [%.2f]", 30 | id1, book1.getTitle(), book1.getPrice(), id2, book2.getTitle(), book2.getPrice()); 31 | 32 | // Use the other service to calculate a total 33 | double total = store.calculatePrice(id1, id2); 34 | printf("Total price (with tax): %.2f", total); 35 | 36 | } 37 | 38 | public static void main(String[] args) { 39 | new Main().start(); 40 | } 41 | 42 | private void printf(String msg, Object... args) { 43 | System.out.println(String.format(msg + "\n", args)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /chapter9/spring-hibernate/src/bookapp/module-info.java: -------------------------------------------------------------------------------- 1 | module bookapp { 2 | requires spring.context; 3 | requires spring.tx; 4 | 5 | requires javax.inject; 6 | 7 | requires hibernate.core; 8 | requires hibernate.jpa; 9 | 10 | exports books.api.entities; 11 | exports books.api.service; 12 | opens books.impl.entities; 13 | opens books.impl.service; 14 | 15 | exports bookstore.api.service; 16 | opens bookstore.impl.service; 17 | } -------------------------------------------------------------------------------- /java9modularity-flat-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/java9-modularity/examples/bc2aa39580e14108e9356f940d03396e376f4654/java9modularity-flat-cover.png --------------------------------------------------------------------------------