Example example_resources

Part of the full Java 9 Jigsaw modules example suite.

Authors

Migrated for Java Modules support documentation of Apache MavenTM in the course of the Maven Support & Care program by Gerd Aschemann (and other team members) as forked repository. Please add discussions, requirements, bugfixes, etc. to the fork instead of the original.

What is this example about?

Modules in this example

  • modb, modc, modmain

  • modmain has a Main class which is started in run.sh

Module Dependency Graph, created with DepVis

Example’s Module Dependency Graph

Example shows resources handling in Java 9 Jigsaw modules

  • modb and modc both have their own resources.properties.

  • They can access it via Module.getResourceAsStream()

  • Note that modb/pkgb.B can also access the resources file in modc

Output

This example uses golden master testing to ensure output consistency. The expected output is compared with actual output using verify.sh.

Expected Output

Main: pkgmain.Main, id=ID_Main_19, B: from B, C: from C
B: Get text from modb's properties: Hello World, from modb's resources.properties
C: Get text from modc's properties: Hello World, from modc's resources.properties
B: Get text from modc's properties: Hello World, from modc's c.properties (whose package is opened) - but retrieved via modb!
Main: Get text from modb's /pkgb/b.properties                 , whose package is opened:                 Hello World, from modb's b.properties (whose package is opened)
Main: Get text from modb's /pkgbinternal/binternal.properties , whose package is not opened:             ERROR: Cannot be loaded
Main: Get text from modc's /pkgc/c.properties                 , whose package is opened:                 Hello World, from modc's c.properties (whose package is opened)
Main: Get text from modc's /pkgcinternal/cinternal.properties , whose package is not opened:             ERROR: Cannot be loaded
Main: Get text from modc's /cnopackage.properties             , whose package is in the unnamed package: Hello World, from modc's cnopackage.properties (whose unnamed package is always not encapsulated)

Actual Output

Main: pkgmain.Main, id=ID_Main_19, B: from B, C: from C
B: Get text from modb's properties: Hello World, from modb's resources.properties
C: Get text from modc's properties: Hello World, from modc's resources.properties
B: Get text from modc's properties: Hello World, from modc's c.properties (whose package is opened) - but retrieved via modb!
Main: Get text from modb's /pkgb/b.properties                 , whose package is opened:                 Hello World, from modb's b.properties (whose package is opened)
Main: Get text from modb's /pkgbinternal/binternal.properties , whose package is not opened:             ERROR: Cannot be loaded
Main: Get text from modc's /pkgc/c.properties                 , whose package is opened:                 Hello World, from modc's c.properties (whose package is opened)
Main: Get text from modc's /pkgcinternal/cinternal.properties , whose package is not opened:             ERROR: Cannot be loaded
Main: Get text from modc's /cnopackage.properties             , whose package is in the unnamed package: Hello World, from modc's cnopackage.properties (whose unnamed package is always not encapsulated)

Maven 4 Output

Main: pkgmain.Main, id=ID_Main_19, B: from B, C: from C
B: Get text from modb's properties: Hello World, from modb's resources.properties
C: Get text from modc's properties: Hello World, from modc's resources.properties
B: Get text from modc's properties: Hello World, from modc's c.properties (whose package is opened) - but retrieved via modb!
Main: Get text from modb's /pkgb/b.properties                 , whose package is opened:                 Hello World, from modb's b.properties (whose package is opened)
Main: Get text from modb's /pkgbinternal/binternal.properties , whose package is not opened:             ERROR: Cannot be loaded
Main: Get text from modc's /pkgc/c.properties                 , whose package is opened:                 Hello World, from modc's c.properties (whose package is opened)
Main: Get text from modc's /pkgcinternal/cinternal.properties , whose package is not opened:             ERROR: Cannot be loaded
Main: Get text from modc's /cnopackage.properties             , whose package is in the unnamed package: Hello World, from modc's cnopackage.properties (whose unnamed package is always not encapsulated)

Maven 4 Migration

This example was migrated to Maven 4 with a special source tree structure to properly separate Java source files from resources, following Maven conventions.

The m4/src directory follows proper Maven directory conventions with separate java/ and resources/ subdirectories:

m4/src/
├── modb/main/
│   ├── java/              # Java source files only
│   │   ├── module-info.java
│   │   ├── pkgb/B.java
│   │   └── pkgbinternal/BInternal.java
│   └── resources/         # Resource files only
│       ├── pkgb/b.properties
│       ├── pkgbinternal/binternal.properties
│       └── resources.modb/resources.properties
├── modc/main/
│   ├── java/              # Java source files only
│   │   ├── module-info.java
│   │   ├── pkgc/C.java
│   │   └── pkgcinternal/CInternal.java
│   └── resources/         # Resource files only
│       ├── cnopackage.properties
│       ├── pkgc/c.properties
│       ├── pkgcinternal/cinternal.properties
│       └── resources.modc/resources.properties
└── modmain/main/
    └── java/              # Java source files only (no resources)
        ├── module-info.java
        ├── pkgmain/Main.java
        └── pkgmaininternal/IdGen.java

This structure differs from the original src/ directory where Java and resource files coexist in the same package directories. The Maven build properly handles resources through explicit maven-resources-plugin configuration that copies resource files from src/<module>/main/resources to target/classes/<module>.

Why Source Files Are Copied, Not Symlinked

Unlike other examples where we use symbolic links to reference the original src/ directory, this example requires full copies of all source files in m4/src/.

The Java compiler cannot properly resolve module structure when individual source files are symlinked from locations outside the module source path. When using --module-source-path, javac expects all files of a module to reside within a single directory tree and fails with "module not found on module source path" errors when encountering symlinks pointing outside that tree.

Therefore, m4/src/ contains actual file copies of all Java sources and resources from the original src/ directory, reorganized into Maven’s standard directory structure.

To ensure consistency between the original sources and the Maven 4 copies, the m4/verify-sources.sh script validates that all files are identical despite the different directory layouts. This script runs automatically as part of m4/verify.sh.