├── .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 | 
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
--------------------------------------------------------------------------------