What is a Java module

A Java module is a collection of classes in a JAR or in a directory that also contain a special class named module-info. If there is this file in a JAR or directory then it is a module, otherwise it is just a collection of classes that are on the classpath (or not). Java 8, and the earlier versions, will just ignore that class as it is never used as code. This way, using older Java, causes no harm and backward compatibility is maintained.

The module information defines what the module exports and what it requires. It has a special format. For example, we can place module-info.java in our SortInterface Maven module.

module packt.java9.by.example.ch03{ 
exports packt.java9.by.example.ch03;
}

This means that any class, which is public and inside the packt.java9.by.example.ch03 package, can be used from outside. This package is exported from the module, but other classes from other packages are not visible from outside of the module even if they are public. The name of the module is same as the package, but this is mere convention in case there is only one package exported. The requirement is the same as in the case of packages: there should be a name that is not likely to collide with other module names. The reversed domain name is a good choice but it is not a must as you can see in this book. There is no top-level domain packt, yet.

We should also configure the parent POM to ensure that the compiler we use is Java 9,

<build> ... 
<plugins> ...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.9</source>
<target>1.9</target>
</configuration>
</plugin>
...

Older versions would be confused with the module-info.java file. (By the way, even the early access version of Java 9 I use for this book sometimes gives a hard time.)

We also create a module-info.java file in the Maven module, quick, which is as follows:

module packt.java9.by.example.ch03.quick{ 
exports packt.java9.by.example.ch03.quick;
requires packt.java9.by.example.ch03;
}

This module exports another package and requires the packt.java9.by.example.ch03 module that we have just created. Now, we can compile the modules and the created JARs in the./quick/target and ./SortInterface/target directories are now Java 9 modules.

As Maven does not fully support the modules yet, when I issue the mvn install command, I get the following error message:
[ERROR] .../genericsort/quick/src/main/java/module-info.java:[3,40] module not found: packt.java9.by.example.ch03
Maven puts the compiled modules on classpath, but Java 9 seeks modulepath for modules. Maven does not handle modulepath yet. To hack modulepath to the compiler, we will have to add the following configuration lines to the parent POM to the configuration of the compiler plugin:<compilerArgs>
<arg>-modulepath</arg>
<arg>${project.parent.basedir}/SortInterface/target/SortInterface-1.0.0-SNAPSHOT.jar: ...</arg>
</compilerArgs>
The actual file should list all the colon separated JAR files that Maven generates, and on which some of the modules depend. These are the SortInterface, quick, and SortSupportClasses.

To test the functionality of module support, we will create another Maven module called Main. It has only one class, called Main, with a public static void main method:

package packt.java9.by.example.ch03.main; 

// ... imports deleted from the print

public class Main {
public static void main(String[] args) throws IOException {
String fileName = args[0];
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(fileName))));
List<String> lines = new LinkedList<>();
String line;
while ((line = br.readLine()) != null) {
lines.add(line);
}
br.close();
String[] lineArray = lines.toArray(new String[0]);
Sort<String> sort = new QuickSort<>();
Qsort<String> qsort = new Qsort<>(String::compareTo,new ArraySwapper<>(lineArray));
sort.setComparator(String::compareTo);
sort.setSwapper(new ArraySwapper<>(lineArray));
sort.sort(new ArrayWrapper<>(lineArray));
for (final String outLine : lineArray) {
System.out.println(outLine);
}
}
}

It takes the first argument (without checking that there is one, which we should not use in a production code) and uses that as a file name. Then, it reads the lines of the file into a String array, sorts it, and prints it to the standard output.

As the module support only works for modules, this Maven module also has to be a Java module and have a module-info.java file.

module packt.java9.by.example.ch03.main{ 
requires packt.java9.by.example.ch03.quick;
requires packt.java9.by.example.ch03;
requires packt.java9.by.example.ch03.support;
}

Additionally, we will have to create a module-info.java file for the support module; otherwise, we will not be able to use it from our module.

After compiling the modules using mvn install, we can run it to print out the parent POM.

    java -cp Main/target/Main-1.0.0-SNAPSHOT.jar:SortInterface/target/SortInterface-1.0.0-SNAPSHOT.jar:quick/target/quick-1.0.0-SNAPSHOT.jar:SortSupportClasses/target/SortSupportClasses-1.0.0-SNAPSHOT.jar packt.java9.by.example.ch03.main.Main pom.xml 
Note that this is one line of command that print breaks into several lines.

Now, if we try to access Qsort directly inserting the following line Qsort<String> qsort = new Qsort<>(String::compareTo,new ArraySwapper<>(lineArray)); into the main method, Maven will complain because the module system hides it from our Main class:

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (default-compile) on project Main: Compilation failure: Compilation failure:
[ERROR] .../Main/src/main/java/packt/java9/by/example/ch03/main/Main.java:[4,41] package packt.java9.by.example.ch03.qsort does not exist
[ERROR] .../Main/src/main/java/packt/java9/by/example/ch03/main/Main.java:[25,9] cannot find symbol

The module system also supports the java.util.ServiceLoader based class-loading mechanism, which we will not discuss in this book. This is an old technology that is rarely used in an enterprise environment when Spring, Guice, or some other dependency injection framework is used. If you see a module-info.java file that contains the uses and provides keywords, then first consult with the Java documentation about the ServiceLoader class at http://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html, and then the Java 9 language documentation on module support (http://openjdk.java.net/projects/jigsaw/quick-start).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.239.41