Show that it works on Java 8:
mvn -v
mvn clean verify
java -cp 'app/*' monitor.Main
In a different terminal:
curl http://localhost:4567/stats/xml
watch -n 1 curl http://localhost:4567/stats/xml
-
start building with Java 9
-
show
mvn -v
-
sdk use java jdk-9
-
show
mvn -v
-
-
create a profile for Java 9+
<profiles> <profile> <id>java-9+</id> <activation> <jdk>[9,)</jdk> </activation> </profile> </profiles>
-
set
release
to 9 in profile<properties> <maven.compiler.release>9</maven.compiler.release> </properties>
-
mvn clean verify
-
fix use of
sun.misc.BASE64Encoder
Base64.getEncoder().encodeToString(content.getBytes());
-
note warning message in monitor.utils
-
fix warning messages in
UtilsTest
in monitor.utils-
create a profile for Java 9
-
show that
illegal-access=deny
disallows access -
configure Surefire to use
--add-opens
<build> <plugins> <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <argLine> --illegal-access=deny --add-opens=java.base/java.lang=ALL-UNNAMED </argLine> </configuration> </plugin> </plugins> </build>
-
better, yet: update Mockito to
2.8.47
-
-
note error package
javax.xml.bind.annotation
is not visible-
open
StatisticsEntity
-
-
add comment
// from module java.xml.bind:
aboveimport XmlElement
-
add java.xml.bind module for annotations in monitor.rest
-
create a profile for Java 9
-
configure compiler to use
--add-modules java.xml.bind
to fix packagejavax.xml.bind.annotation
is not visible<build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <compilerArgs> <arg>--add-modules=java.xml.bind</arg> </compilerArgs> </configuration> </plugin> </plugins> </build>
-
-
observe error: cannot find symbol for missing type
Generated
-
open
StatisticsEntity
-
-
add java.xml.ws.annotation to monitor.rest to fix missing type
Generated
-
observe that error contains no hint of the containing module
-
look up module in documentation
-
add comment
// from module java.xml.ws.annotation:
aboveimport Generated
-
add java.xml.ws.annotation
<arg>--add-modules=java.xml.ws.annotation</arg>
-
observe new missing types problem
-
-
patch java.xml.ws.annotation with JSR classes
<arg>--patch-module=java.xml.ws.annotation=${settings.localRepository}/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar</arg>
-
replace
maven.compiler.release
withmaven.compiler.source
andmaven.compiler.target
in parent POM
Start running with Java 9:
java --class-path 'app/*' monitor.Main
-
fix cast to
URLClassLoader
by replacing code inlogClassPathContent
withString[] classPath = System.getProperty("java.class.path").split(":"); String message = Arrays.stream(classPath) .map(url -> "\t" + url) .collect(joining("\n", "Class path content:\n", "\n")); System.out.println(message);
-
add module
java.xml.bind
java --add-modules java.xml.bind --class-path 'app/*' monitor.Main
-
note that
--add-exports
,--add-opens
,--add-modules
,--patch-module
usually carry from build to compile time
-
update to 10 with
sdk use java jdk-10
-
show
mvn -v
-
limit parent POM profile for Java 9+ to 9 and copy paste to create one for 10
<profile> <id>java-10</id> <activation> <jdk>10</jdk> </activation> <properties> <maven.compiler.source>10</maven.compiler.source> <maven.compiler.target>10</maven.compiler.target> </properties> </profile>
-
to use
var
somewhere, activate java-10 profile in IntelliJ and reimport -
build with
mvn clean verify
-
fix error in monitor.utils by updating Mockito to 2.18.3
-
in parent POM’s Java 10 profile update ASM to preempt compiler problems
<build> <plugins> <!-- if compilation fails, try newer version of ASM https://stackoverflow.com/q/49398894/2525313 --> <plugin> <artifactId>maven-compiler-plugin</artifactId> <dependencies> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> <version>6.1.1</version> </dependency> </dependencies> </plugin> </plugins> </build>
-
run with
java --add-modules java.xml.bind --class-path 'app/*' monitor.Main
-
update to 11 with
sdk use java jdk-11
-
show
mvn -v
-
in parent POM update compiler plugin to 3.8.0
remove ASM update in profilejava-10
-
in parent POM copy paste profile to create one for 11
<profile> <id>java-11</id> <activation> <jdk>11</jdk> </activation> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> </profile>
-
build with
mvn clean verify
-
in monitor.rest's POM, show how to edit profile to only be active for 9, 10:
<id>java-9-01</id> <activation> <jdk>[9,10]</jdk> </activation>
-
then remove profile and add third-party dependencies in monitor.rest's POM:
<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.0</version> </dependency>
-
run with
java --class-path 'app/*' monitor.Main
-
observe that
xml
endpoint does not return anything, butjson
does -
activate
java-11
profile, reimport, and launch from IntelliJ -
in
MonitorServer
changecatch (JAXBException ex)
tocatch (Throwable ex)
and observe the error -
add this dependency:
<!-- HOW?! --> <dependency> <groupId>com.sun.activation</groupId> <artifactId>javax.activation</artifactId> <version>1.2.0</version> </dependency>
(Was not needed before because
java.xml.bind
requires it) -
point out illegal access warning (if present) and replace all dependencies in monitor.rest with:
<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.3</version> </dependency>
-
in parent POM, replace compiler source and target 8 with release 11
-
remove version-specific profiles
-
see artifact dependencies
jdeps -summary -recursive --class-path 'app/*' --multi-release 11 app/main.jar
-
limiting to Monitor classes
jdeps -summary -recursive --class-path 'app/*' --multi-release 11 -include 'monitor.*' app/main.jar
-
create a diagram
jdeps -summary -recursive --class-path 'app/*' --multi-release 11 -include 'monitor.*' --dot-output . app/main.jar dot -Tpng -O summary.dot gwenview summary.dot.png
-
clean up graph
sed -i '/java.base/d' summary.dot sed -i 's/.jar//g' summary.dot dot -Tpng -O summary.dot gwenview summary.dot.png &
-
start with monitor.utils
-
modularize monitor.utils
module monitor.utils { exports monitor.utils; }
-
build with Maven
-
observe that monitor.utils is module:
jar --describe-module --file app/utils.jar
-
observe that the module works on the class path:
java --class-path 'app/*' monitor.Main
-
make it work on module path
-
create
move-modules.sh
#!/bin/bash set -e rm -rf mods mkdir mods
and make it executable with
chmod +x move-modules.sh
-
add
mv app/utils.jar mods
tomove-modules.sh
-
create
run.sh
#!/bin/bash set -e
-
try to run
# fails java --class-path 'app/*' --module-path mods monitor.Main # too noisy java --class-path 'app/*' --module-path mods \ --show-module-resolution monitor.Main # no utils java --class-path 'app/*' --module-path mods \ --show-module-resolution monitor.Main | grep utils # yes utils! java --class-path 'app/*' --module-path mods \ --add-modules monitor.utils \ --show-module-resolution monitor.Main | grep utils # launch java --class-path 'app/*' --module-path mods \ --add-modules monitor.utils \ monitor.Main
-
-
-
continue with observers
-
modularize monitor.observer:
module monitor.observer { exports monitor.observer; }
-
modularize monitor.observer.alpha:
module monitor.observer.alpha { requires monitor.observer; exports monitor.observer.alpha; }
-
modularize monitor.observer.beta:
module monitor.observer.beta { requires monitor.observer; exports monitor.observer.beta; }
-
in monitor.observer.alpha, show with
mvn -X compiler
class/module path -
add
mv app/observer* mods
tomove-modules.sh
-
run
java --class-path 'app/*' --module-path mods \ --add-modules monitor.utils,monitor.observer.alpha,monitor.observer.beta \ monitor.Main
-
-
modularize statistics as preparation for monitor.rest
-
modularize monitor.statistics
module monitor.statistics { requires monitor.observer; exports monitor.statistics; }
-
add
mv app/statistics.jar mods
tomove-modules.sh
-
run
java --class-path 'app/*' --module-path mods \ --add-modules monitor.utils,monitor.observer.alpha,monitor.observer.beta,monitor.statistics \ monitor.Main
-
-
modularize monitor.rest in face of unmodularized dependencies
-
create initial module descriptor
module monitor.rest { requires java.xml.bind; requires monitor.utils; requires monitor.statistics; exports monitor.rest; }
-
use
jar11 --describe-module-file --file spark-core
etc to determine module names -
add
requires
for spark.core, jackson.core, jackson.databind to module descriptor -
identify split package between jsr305 and java.annotation
-
add
requires java.annotation
-
patch package split:
<build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <compilerArgs> <arg>--patch-module=java.annotation=${settings.localRepository}/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar</arg> </compilerArgs> </configuration> </plugin> </plugins> </build>
-
add to
move-modules.sh
:mv app/jaxb-api.jar mods mv app/javax.activation.jar mods mv app/javax.annotation-api.jar mods mv app/spark-core.jar mods mv app/jackson-core.jar mods mv app/jackson-databind.jar mods
-
run
java --class-path 'app/*' --module-path mods \ --add-modules monitor.rest,monitor.observer.alpha,monitor.observer.beta \ monitor.Main
-
mention that
--patch-module
is not needed because annotations are not evaluated at run time -
observe run-time error in
watch
tab -
add
opens monitor.rest to java.xml.bind;
to monitor.rest
-