You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2018/06/20 14:16:00 UTC

[sis] branch JDK9 updated (8f793f2 -> 6e2dfa0)

This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a change to branch JDK9
in repository https://gitbox.apache.org/repos/asf/sis.git.


 discard 8f793f2  Partial compatibility with JDK9 in root pom.xml, NetBeans configuration and doclet.
    omit 4b09956  Renamed the NetBeans project from "Apache SIS on JDK8" to "Apache SIS on GeoAPI 4.0".
    omit 06ded49  Fix a never-ending loop when the file to open has a known extensions but is still not recognized as a known format. This happen in particular with XML files.
    omit ebbbd00  Portrayal : remove final and extend MapItem on MapLayer class
    omit 4b659ec  Call to Field.setAccessible(true) need to take in account security constrained environment. Call to ModifiableMetadata.freeze() share instances when possible.
    omit 13287c5  Update dependencies.
    omit 97c929c  Take in account the change in number of dimensions when creating GeoTIFF GridGeometry. Fill more metadata using GridGeometry information.
    omit 2b65ffd  Move PassThroughTransform.create(…) method to MathTransforms.passThrough(…).
    omit 2ca9d06  Fix error messages for illegal grid geometries.
    omit de98170  First draft of a GeoTIFF reader capable to compute the GridGeometry.
    omit 865bc32  Renamed GridGeometry as Localization for avoiding confusion with GridGeometry in sis-raster.
    omit dc37d24  Remove Numerics.hashCode(long), replaced by Long.hashCode(long).
    omit a2f6e8e  First draft of a GridCoverageResource interface.
    omit bffe00d  Use the 'long' primitive type instead of 'int' in GridExtent. This force us to not implement GeoAPI interfaces for now (until https://github.com/opengeospatial/geoapi/issues/36) is resolved. But since those interfaces were not part of formal standard yet (they are in the "pending" part of GeoAPI), we would not have implemented them in SIS release anyway.
    omit 3044387  Add abbreviations for all sub-interfaces found in ISO 19115 except quality package.
    omit a1b635e  Remember the filter used last time the user opened a file.
    omit f60046d  SQL metadaat: fix an "ID column not found" error on PostgreSQL, more compact identifiers, and replace CRS WKT by EPSG codes.
    omit f60835a  Leverage geoapi-conformance for reading OGC XSD files.
    omit e5688f4  More robust parsing of GeoTIFF tags: when expecting a single value, accept an array if all values are the same. Also accept -1 as a code for "missing units" but verify if the unit is really missing.
    omit 9df4509  Method renaming and javadoc.
    omit cc37d16  Add tests for GridGeometry.
    omit 2456207  Improve GridGeometry documentation and add a isConversionLinear method.
    omit 07393dd  Computes resolution at GridGeometry construction time.
    omit 9de0edd  Remove @Debug annotation on toString() methods in order to avoid polluting the list of debug methods with long list of toString() methods. Unless otherwise specified in javadoc, toString() will be considered implicitly for debugging purpose.
    omit 895a741  Documentation clarification in GridExtent.
    omit 4e87142  Added documentation and tests for PixelTranslation.
    omit b5b210b  First draft of a port of GridGeometry class, for grid coverage (raster) support.
    omit 7f9281c  Take axis direction in account when computing the geographic bounding box.
    omit d4920d3  When opening a dataset, try the DataStoreProvider for the file extension before to try any other DataStoreProvider. The intent is to avoid DataStoreProvider.probeContent(...) invocation that may cause loading of large dependencies.
    omit cc090f4  Initial review of GUI main class (localization, file filters).
    omit 0cc2ba4  Initial commit of Smaniotto Enzo work from SIS-417, with some renaming.
    omit 3e98214  Remove the "Longitude first" checkbox from CRSChooser - this is not the right widget were to provide this choice.
    omit 29401b4  Move GUI resources in internal package. Rename "gui.crs" as "gui.referencing". Deprecate the methods that introduce a dependency to AWT.
    omit e25aebe  Ignore a test that depends on a shapefile removed from history. See https://issues.apache.org/jira/browse/SIS-422
     add dae7e95  Renamed the NetBeans project from "Apache SIS on JDK8" to "Apache SIS on GeoAPI 4.0".
     add 4b40f64  Tuning: netbeans project configuration, serialVersionUID of objects that are different between branches.
     add 3e7278c  Replace reference to trunk by reference to master, and avoid reference to JDK8 branch.
     add 6937949  Ignore a test that depends on a shapefile removed from history. See https://issues.apache.org/jira/browse/SIS-422
     new 6e2dfa0   Partial compatibility with JDK9 in root pom.xml, NetBeans configuration and doclet.

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (8f793f2)
            \
             N -- N -- N   refs/heads/JDK9 (6e2dfa0)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/apache/sis/console/package-info.java  |   2 +-
 .../src/main/java/org/apache/sis/gui/Main.java     | 204 ------
 .../apache/sis/{internal => }/gui/Resources.java   |  94 ++-
 .../sis/{internal => }/gui/Resources.properties    |   9 +-
 .../sis/{internal => }/gui/Resources_fr.properties |   9 +-
 .../sis/gui/{referencing => crs}/CRSButton.java    |   2 +-
 .../sis/gui/{referencing => crs}/CRSChooser.java   |  81 +-
 .../sis/gui/{referencing => crs}/CRSTable.java     |  69 +-
 .../apache/sis/gui/{referencing => crs}/Code.java  |  54 +-
 .../FormattableObjectPane.java}                    |  16 +-
 .../org/apache/sis/gui/metadata/MetadataNode.java  | 228 ------
 .../apache/sis/gui/metadata/MetadataOverview.java  | 432 -----------
 .../org/apache/sis/gui/metadata/ResourceView.java  | 312 --------
 .../org/apache/sis/internal/gui/FXUtilities.java   |  91 ---
 .../org/apache/sis/internal/gui/FontGlyphs.java    |  13 +-
 .../apache/sis/internal/gui/JavaFxUtilities.java   |  98 +++
 .../org/apache/sis/internal/gui/package-info.java  |  31 -
 .../org/apache/sis/gui/crs/CRSChooser.fxml         |  36 +
 .../sis/gui/{referencing => crs}/proj_conic.png    | Bin
 .../sis/gui/{referencing => crs}/proj_geo.png      | Bin
 .../sis/gui/{referencing => crs}/proj_square.png   | Bin
 .../sis/gui/{referencing => crs}/proj_stereo.png   | Bin
 .../sis/gui/{referencing => crs}/proj_utm.png      | Bin
 .../org/apache/sis/gui/referencing/CRSChooser.fxml |  30 -
 .../apache/sis/feature/AbstractAssociation.java    |   2 +
 .../org/apache/sis/feature/AbstractAttribute.java  |   2 +
 .../org/apache/sis/feature/AbstractOperation.java  |   2 +
 .../apache/sis/feature/DefaultAssociationRole.java |   2 +
 .../apache/sis/feature/DefaultAttributeType.java   |   2 +
 .../java/org/apache/sis/feature/PropertyView.java  |   2 +
 .../apache/sis/feature/builder/TypeBuilder.java    |   2 +
 .../sis/internal/jaxb/IdentifierMapAdapter.java    |   3 +
 .../sis/internal/jaxb/SpecializedIdentifier.java   |   2 +
 .../jaxb/lan/LocalisedCharacterString.java         |   2 +
 .../apache/sis/internal/jaxb/lan/TextGroup.java    |   2 +
 .../sis/internal/metadata/ReferencingServices.java |  16 +-
 .../sis/internal/metadata/sql/SQLBuilder.java      |  16 +-
 .../sis/internal/simple/CitationConstant.java      |   2 +
 .../apache/sis/internal/simple/SimpleCitation.java |   4 +-
 .../apache/sis/internal/simple/SimpleFormat.java   |   2 +
 .../sis/internal/simple/SimpleIdentifier.java      |   2 +
 .../main/java/org/apache/sis/io/wkt/Element.java   |   1 +
 .../main/java/org/apache/sis/io/wkt/Formatter.java |   2 +
 .../java/org/apache/sis/metadata/CacheKey.java     |   2 +
 .../main/java/org/apache/sis/metadata/Freezer.java |  65 +-
 .../org/apache/sis/metadata/MetadataStandard.java  |  18 +-
 .../apache/sis/metadata/ModifiableMetadata.java    |   8 +-
 .../java/org/apache/sis/metadata/ObjectPair.java   |   2 +
 .../org/apache/sis/metadata/PropertyAccessor.java  |  22 +-
 .../sis/metadata/StandardImplementation.java       |   2 +-
 .../java/org/apache/sis/metadata/TreeNode.java     |   2 +
 .../org/apache/sis/metadata/TreeNodeChildren.java  |   2 +
 .../apache/sis/metadata/iso/DefaultMetadata.java   |  16 +-
 .../org/apache/sis/metadata/iso/ISOMetadata.java   |   7 +-
 .../sis/metadata/iso/citation/Citations.java       |   2 +-
 .../sis/metadata/iso/citation/DefaultAddress.java  |   4 +-
 .../sis/metadata/iso/citation/DefaultContact.java  |   2 +-
 .../iso/citation/DefaultOnlineResource.java        |   2 +-
 .../java/org/apache/sis/metadata/package-info.java |   2 +-
 .../apache/sis/metadata/sql/MetadataSource.java    |  42 +-
 .../apache/sis/metadata/sql/MetadataWriter.java    |  57 +-
 .../apache/sis/metadata/sql/TableHierarchy.java    | 118 ---
 .../org/apache/sis/util/iso/DefaultNameSpace.java  |   2 +
 .../org/apache/sis/util/iso/DefaultRecord.java     |   2 +
 .../apache/sis/util/iso/DefaultRecordSchema.java   |   2 +
 .../org/apache/sis/util/iso/RecordDefinition.java  |   2 +
 .../org/apache/sis/metadata/iso/APIVerifier.java   |   4 +-
 .../org/apache/sis/test/xml/PackageVerifier.java   |  45 +-
 .../org/apache/sis/test/xml/SchemaCompliance.java  | 382 +++++++++-
 .../org/apache/sis/test/xml/SchemaException.java}  |  17 +-
 .../org/apache/sis/xml/RenameListGenerator.java    |   2 +-
 .../apache/sis/metadata/iso/api-changes.properties |   2 +-
 .../java/org/apache/sis/internal/map/MapLayer.java |   2 +-
 core/sis-raster/pom.xml                            |  16 +-
 .../sis/coverage/grid/GridCoordinatesView.java     | 136 ----
 .../org/apache/sis/coverage/grid/GridExtent.java   | 510 -------------
 .../org/apache/sis/coverage/grid/GridGeometry.java | 815 ---------------------
 .../grid/IncompleteGridGeometryException.java      |  70 --
 .../apache/sis/coverage/grid/PixelTranslation.java | 366 ---------
 .../java/org/apache/sis/image/DefaultIterator.java |   4 +-
 .../java/org/apache/sis/image/PixelIterator.java   |   4 +-
 .../java/org/apache/sis/image/TransferType.java    |   4 +-
 .../apache/sis/image/WritablePixelIterator.java    |   4 +-
 .../java/org/apache/sis/image/package-info.java    |   4 +-
 .../org/apache/sis/internal/raster/Resources.java  |  45 +-
 .../sis/internal/raster/Resources.properties       |   4 -
 .../sis/internal/raster/Resources_fr.properties    |   4 -
 .../apache/sis/internal/raster/package-info.java   |   4 +-
 .../apache/sis/coverage/grid/GridGeometryTest.java | 190 -----
 .../sis/coverage/grid/PixelTranslationTest.java    | 124 ----
 .../org/apache/sis/image/DefaultIteratorTest.java  |   4 +-
 .../org/apache/sis/test/suite/RasterTestSuite.java |   8 +-
 .../referencing/gazetteer/AbstractLocation.java    |   2 +
 .../gazetteer/MilitaryGridReferenceSystem.java     |   2 +
 .../sis/geometry/AbstractDirectPosition.java       |   3 +-
 .../org/apache/sis/geometry/AbstractEnvelope.java  |   3 +-
 .../org/apache/sis/geometry/DirectPosition1D.java  |   3 +-
 .../org/apache/sis/geometry/DirectPosition2D.java  |   4 +-
 .../org/apache/sis/geometry/GeneralEnvelope.java   |  12 +-
 .../referencing/PositionalAccuracyConstant.java    |   1 +
 .../internal/referencing/ServicesForMetadata.java  |  32 +-
 .../referencing/provider/DatumShiftGridFile.java   |   2 +
 .../sis/parameter/AbstractParameterDescriptor.java |   1 +
 .../java/org/apache/sis/parameter/Parameters.java  |   1 +
 .../org/apache/sis/parameter/TensorParameters.java |   9 +-
 .../sis/referencing/AbstractIdentifiedObject.java  |   5 +-
 .../apache/sis/referencing/IdentifiedObjects.java  |  34 +-
 .../sis/referencing/cs/DirectionAlongMeridian.java |   2 +-
 .../sis/referencing/datum/BursaWolfParameters.java |   2 +-
 .../sis/referencing/datum/TimeDependentBWP.java    |   3 +-
 .../factory/AuthorityFactoryIdentifier.java        |   2 +
 .../factory/ConcurrentAuthorityFactory.java        |   4 +-
 .../factory/GeodeticAuthorityFactory.java          |   2 +
 .../referencing/factory/sql/AuthorityCodes.java    |   2 +
 .../sis/referencing/factory/sql/AxisName.java      |   2 +
 .../operation/CoordinateOperationRegistry.java     |   6 +-
 .../operation/DefaultPassThroughOperation.java     |   5 +-
 .../operation/builder/LinearTransformBuilder.java  |   2 +
 .../sis/referencing/operation/matrix/Matrix1.java  |   2 +-
 .../sis/referencing/operation/matrix/Matrix2.java  |   2 +-
 .../operation/projection/NormalizedProjection.java |   2 +-
 .../operation/projection/ZonedGridSystem.java      |   2 +-
 .../operation/transform/ConcatenatedTransform.java |   2 +-
 .../transform/DefaultMathTransformFactory.java     |   2 +-
 .../transform/EllipsoidToCentricTransform.java     |   2 +-
 .../transform/ExponentialTransform1D.java          |   2 +-
 .../operation/transform/LinearTransform1D.java     |   3 +-
 .../transform/LogarithmicTransform1D.java          |   2 +-
 .../operation/transform/MathTransforms.java        |  45 +-
 .../operation/transform/MolodenskyFormula.java     |   2 +-
 .../operation/transform/PassThroughTransform.java  |  64 +-
 .../operation/transform/PowerTransform1D.java      |   2 +-
 .../operation/transform/TransferFunction.java      |   2 +
 .../transform/ConcatenatedTransformTest.java       |   2 +-
 .../operation/transform/MathTransformsTest.java    |   2 +-
 .../transform/PassThroughTransformTest.java        |   8 +-
 .../transform/TransformSeparatorTest.java          |   2 +-
 .../apache/sis/internal/converter/ClassPair.java   |   2 +
 .../sis/internal/converter/ConverterRegistry.java  |   2 +
 .../sis/internal/converter/FallbackConverter.java  |   2 +
 .../internal/converter/SurjectiveConverter.java    |   2 +
 .../org/apache/sis/internal/system/Supervisor.java |   2 +-
 .../apache/sis/internal/util/AbstractMapEntry.java |   2 +
 .../java/org/apache/sis/internal/util/Cloner.java  |   1 -
 .../org/apache/sis/internal/util/DoubleDouble.java |   2 +-
 .../apache/sis/internal/util/FinalFieldSetter.java | 157 ----
 .../org/apache/sis/internal/util/Numerics.java     |  10 +
 .../sis/internal/util/StandardDateFormat.java      |   8 -
 .../sis/internal/util/TemporalUtilities.java       |   2 +-
 .../org/apache/sis/internal/util/Utilities.java    |   2 +-
 .../src/main/java/org/apache/sis/math/Line.java    |   2 +-
 .../src/main/java/org/apache/sis/math/Plane.java   |   2 +-
 .../java/org/apache/sis/measure/AngleFormat.java   |   2 +
 .../org/apache/sis/measure/LinearConverter.java    |   8 +-
 .../java/org/apache/sis/measure/RangeFormat.java   |  20 +-
 .../java/org/apache/sis/measure/UnitFormat.java    |  21 +-
 .../java/org/apache/sis/util/CharSequences.java    |   4 +-
 .../apache/sis/util/CorruptedObjectException.java  |  13 +-
 .../src/main/java/org/apache/sis/util/Debug.java   |  20 +-
 .../main/java/org/apache/sis/util/Exceptions.java  |   4 -
 .../sis/util/collection/BackingStoreException.java |   5 +-
 .../apache/sis/util/logging/WarningListeners.java  |   8 +-
 .../java/org/apache/sis/util/resources/Errors.java |   5 -
 .../apache/sis/util/resources/Errors.properties    |   1 -
 .../apache/sis/util/resources/Errors_fr.properties |   1 -
 .../sis/util/resources/IndexedResourceBundle.java  |   1 +
 .../org/apache/sis/util/resources/Vocabulary.java  |  17 +-
 .../sis/util/resources/Vocabulary.properties       |   3 -
 .../sis/util/resources/Vocabulary_fr.properties    |   3 -
 .../org/apache/sis/internal/util/CitationMock.java |   2 +
 .../sis/internal/util/StandardDateFormatTest.java  |   2 -
 ide-project/NetBeans/nbproject/genfiles.properties |   2 +-
 ide-project/NetBeans/nbproject/project.properties  |   4 +
 ide-project/NetBeans/nbproject/project.xml         |   1 +
 pom.xml                                            |  12 +-
 .../sis/storage/earthobservation/LandsatStore.java |   2 +
 .../org/apache/sis/internal/geotiff/Resources.java |   5 -
 .../sis/internal/geotiff/Resources.properties      |   1 -
 .../sis/internal/geotiff/Resources_fr.properties   |   1 -
 .../org/apache/sis/storage/geotiff/CRSBuilder.java | 148 ++--
 .../org/apache/sis/storage/geotiff/GeoCodes.java   |   8 +-
 .../{Localization.java => GridGeometry.java}       | 123 +++-
 .../sis/storage/geotiff/GridGeometryBuilder.java   | 390 ----------
 .../sis/storage/geotiff/ImageFileDirectory.java    | 191 +++--
 .../java/org/apache/sis/storage/geotiff/Type.java  | 259 +++----
 .../org/apache/sis/storage/geotiff/TypeTest.java   |  23 +-
 .../java/org/apache/sis/internal/netcdf/Axis.java  |  29 +-
 .../org/apache/sis/internal/netcdf/Decoder.java    |  25 +-
 .../apache/sis/internal/netcdf/GridGeometry.java   |   7 +-
 .../org/apache/sis/internal/netcdf/Variable.java   |   2 +
 .../sis/internal/netcdf/impl/ChannelDecoder.java   |   2 +
 .../apache/sis/internal/netcdf/impl/Dimension.java |   2 +
 .../sis/internal/netcdf/impl/GridGeometryInfo.java |   2 +-
 .../sis/internal/netcdf/impl/package-info.java     |   2 +-
 .../apache/sis/internal/netcdf/package-info.java   |   6 +-
 .../sis/internal/netcdf/ucar/DecoderWrapper.java   |   2 +
 .../sis/internal/netcdf/ucar/package-info.java     |   7 +-
 .../apache/sis/storage/netcdf/MetadataReader.java  | 160 ++--
 .../org/apache/sis/storage/netcdf/NetcdfStore.java |   2 +
 .../apache/sis/storage/netcdf/package-info.java    |   2 +-
 .../internal/netcdf/impl/ChannelDecoderTest.java   |   3 +-
 .../sis/internal/sql/reverse/SchemaMetaModel.java  |   2 +
 .../sis/internal/sql/reverse/TableMetaModel.java   |   2 +
 storage/sis-storage/pom.xml                        |   5 -
 .../sis/internal/storage/MetadataBuilder.java      |  92 +--
 .../sis/internal/storage/StoreUtilities.java       |   2 +-
 .../sis/internal/storage/io/ChannelData.java       |   2 +
 .../sis/internal/storage/io/IOUtilities.java       |   6 +-
 .../sis/internal/storage/query/SimpleQuery.java    |   2 +
 .../org/apache/sis/storage/DataStoreRegistry.java  | 133 ++--
 .../apache/sis/storage/GridCoverageResource.java   |  40 -
 .../org/apache/sis/storage/ProbeProviderPair.java  |   5 +-
 .../java/org/apache/sis/storage/ProbeResult.java   |   2 +
 .../org/apache/sis/storage/StorageConnector.java   |   2 +
 .../internal/storage/xml/stream/StaxDataStore.java |   2 +
 .../sis/internal/storage/gpx/WriterTest.java       |   2 +
 216 files changed, 1776 insertions(+), 5612 deletions(-)
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/Main.java
 rename application/sis-javafx/src/main/java/org/apache/sis/{internal => }/gui/Resources.java (62%)
 rename application/sis-javafx/src/main/java/org/apache/sis/{internal => }/gui/Resources.properties (86%)
 rename application/sis-javafx/src/main/java/org/apache/sis/{internal => }/gui/Resources_fr.properties (83%)
 rename application/sis-javafx/src/main/java/org/apache/sis/gui/{referencing => crs}/CRSButton.java (98%)
 rename application/sis-javafx/src/main/java/org/apache/sis/gui/{referencing => crs}/CRSChooser.java (61%)
 rename application/sis-javafx/src/main/java/org/apache/sis/gui/{referencing => crs}/CRSTable.java (86%)
 rename application/sis-javafx/src/main/java/org/apache/sis/gui/{referencing => crs}/Code.java (60%)
 rename application/sis-javafx/src/main/java/org/apache/sis/gui/{referencing/WKTPane.java => crs/FormattableObjectPane.java} (88%)
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataNode.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataOverview.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/ResourceView.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/FXUtilities.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/JavaFxUtilities.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/package-info.java
 create mode 100644 application/sis-javafx/src/main/resources/org/apache/sis/gui/crs/CRSChooser.fxml
 rename application/sis-javafx/src/main/resources/org/apache/sis/gui/{referencing => crs}/proj_conic.png (100%)
 rename application/sis-javafx/src/main/resources/org/apache/sis/gui/{referencing => crs}/proj_geo.png (100%)
 rename application/sis-javafx/src/main/resources/org/apache/sis/gui/{referencing => crs}/proj_square.png (100%)
 rename application/sis-javafx/src/main/resources/org/apache/sis/gui/{referencing => crs}/proj_stereo.png (100%)
 rename application/sis-javafx/src/main/resources/org/apache/sis/gui/{referencing => crs}/proj_utm.png (100%)
 delete mode 100644 application/sis-javafx/src/main/resources/org/apache/sis/gui/referencing/CRSChooser.fxml
 delete mode 100644 core/sis-metadata/src/main/java/org/apache/sis/metadata/sql/TableHierarchy.java
 rename core/{sis-raster/src/main/java/org/apache/sis/coverage/grid/package-info.java => sis-metadata/src/test/java/org/apache/sis/test/xml/SchemaException.java} (61%)
 delete mode 100644 core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridCoordinatesView.java
 delete mode 100644 core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
 delete mode 100644 core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java
 delete mode 100644 core/sis-raster/src/main/java/org/apache/sis/coverage/grid/IncompleteGridGeometryException.java
 delete mode 100644 core/sis-raster/src/main/java/org/apache/sis/coverage/grid/PixelTranslation.java
 delete mode 100644 core/sis-raster/src/test/java/org/apache/sis/coverage/grid/GridGeometryTest.java
 delete mode 100644 core/sis-raster/src/test/java/org/apache/sis/coverage/grid/PixelTranslationTest.java
 delete mode 100644 core/sis-utility/src/main/java/org/apache/sis/internal/util/FinalFieldSetter.java
 rename storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/{Localization.java => GridGeometry.java} (66%)
 delete mode 100644 storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GridGeometryBuilder.java
 delete mode 100644 storage/sis-storage/src/main/java/org/apache/sis/storage/GridCoverageResource.java


[sis] 01/01: Partial compatibility with JDK9 in root pom.xml, NetBeans configuration and doclet.

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch JDK9
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 6e2dfa0fd1e83f9f3b67df7932484e80ca161c33
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Wed Jun 20 16:13:58 2018 +0200

     Partial compatibility with JDK9 in root pom.xml, NetBeans configuration and doclet.
---
 core/sis-build-helper/pom.xml                      |  55 +-
 .../org/apache/sis/internal/doclet/Doclet.java     | 105 ++-
 .../sis/internal/{taglet => doclet}/Include.java   |  42 +-
 .../apache/sis/internal/doclet/InlineTaglet.java   | 158 ++++
 .../org/apache/sis/internal/doclet/Module.java     | 113 +++
 .../sis/internal/{taglet => doclet}/Preformat.java |  50 +-
 .../apache/sis/internal/doclet/package-info.java   |   5 +-
 .../apache/sis/internal/taglet/InlineTaglet.java   | 170 -----
 .../org/apache/sis/internal/taglet/Module.java     | 182 -----
 .../apache/sis/internal/taglet/package-info.java   |  27 -
 .../org/apache/sis/measure/RangeFormatTest.java    |  18 +-
 .../src/test/java/org/apache/sis/test/Assert.java  |   6 +-
 ide-project/NetBeans/nbproject/build-impl.xml      | 818 ++++++++++++++-------
 ide-project/NetBeans/nbproject/genfiles.properties |   4 +-
 ide-project/NetBeans/nbproject/project.properties  |  22 +-
 pom.xml                                            |  34 +-
 16 files changed, 990 insertions(+), 819 deletions(-)

diff --git a/core/sis-build-helper/pom.xml b/core/sis-build-helper/pom.xml
index f3b6e97..03f10de 100644
--- a/core/sis-build-helper/pom.xml
+++ b/core/sis-build-helper/pom.xml
@@ -88,6 +88,14 @@
   <build>
     <plugins>
       <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <compilerArgs>
+            <arg>--add-modules</arg> <arg>jdk.javadoc</arg>
+          </compilerArgs>
+        </configuration>
+      </plugin>
+      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-plugin-plugin</artifactId>
         <version>3.5</version>
@@ -133,51 +141,4 @@
     </dependency>
   </dependencies>
 
-
-  <!-- ===========================================================
-           Sun's tools dependency   (from Maven FAQ)
-       =========================================================== -->
-  <profiles>
-    <profile>
-      <id>default-tools.jar</id>
-      <activation>
-        <property>
-          <name>java.vendor</name>
-          <value>Sun Microsystems Inc.</value>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>com.sun</groupId>
-          <artifactId>tools</artifactId>
-          <version>${java.version}</version>
-          <scope>system</scope>
-          <systemPath>${java.home}/../lib/tools.jar</systemPath>
-        </dependency>
-      </dependencies>
-    </profile>
-
-    <!-- Following is a copy of the above profile with only the Java vendor name changed.
-         This copy will not be needed anymore if http://jira.codehaus.org/browse/MNG-3328
-         get fixed. -->
-    <profile>
-      <id>jdk8-tools.jar</id>
-      <activation>
-        <property>
-          <name>java.vendor</name>
-          <value>Oracle Corporation</value>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>com.sun</groupId>
-          <artifactId>tools</artifactId>
-          <version>${java.version}</version>
-          <scope>system</scope>
-          <systemPath>${java.home}/../lib/tools.jar</systemPath>
-        </dependency>
-      </dependencies>
-    </profile>
-  </profiles>
-
 </project>
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Doclet.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Doclet.java
index 654f694..24a0478 100644
--- a/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Doclet.java
+++ b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Doclet.java
@@ -16,6 +16,10 @@
  */
 package org.apache.sis.internal.doclet;
 
+import java.util.Set;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Locale;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -29,8 +33,11 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.nio.file.FileSystemException;
 import java.nio.file.Files;
-import com.sun.javadoc.RootDoc;
-import com.sun.tools.doclets.formats.html.HtmlDoclet;
+import javax.tools.Diagnostic;
+import jdk.javadoc.doclet.Reporter;
+import jdk.javadoc.doclet.Doclet.Option;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.StandardDoclet;
 
 
 /**
@@ -50,11 +57,11 @@ import com.sun.tools.doclets.formats.html.HtmlDoclet;
  * <p>This class presumes that all CSS files are encoded in UTF-8.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.5
  * @module
  */
-public final class Doclet extends HtmlDoclet {
+public final class Doclet extends StandardDoclet {
     /**
      * The name of the standard stylesheet file generated by Javadoc.
      */
@@ -76,27 +83,81 @@ public final class Doclet extends HtmlDoclet {
     private static final String ENCODING = "UTF-8";
 
     /**
-     * Invoked by reflection for creating the doclet.
+     * The directory where HTML pages will be written.
+     */
+    private String outputDirectory;
+
+    /**
+     * Where to report warnings, or {@code null} if unknown.
+     */
+    Reporter reporter;
+
+    /**
+     * Invoked by the Javadoc tools for instantiating the custom doclet.
      */
     public Doclet() {
     }
 
     /**
-     * Invoked by Javadoc for starting the doclet.
+     * Invoked by the Javadoc tools for initializing the doclet.
      *
-     * @param  root  the root document.
-     * @return {@code true} on success, or {@code false} on failure.
+     * @param locale    the locale to use for formatting HTML content.
+     * @param reporter  where to report warnings and errors.
      */
-    public static boolean start(final RootDoc root) {
-        String outputDirectory = null;
-        for (final String[] option : root.options()) {
-            if (option.length == 2) {
-                if ("-d".equals(option[0])) {
-                    outputDirectory = option[1];
-                }
+    @Override
+    public void init(final Locale locale, final Reporter reporter) {
+        super.init(locale, reporter);
+        this.reporter = reporter;
+    }
+
+    /**
+     * Returns the options supported by the standard doclet.
+     *
+     * @return all the supported options.
+     */
+    @Override
+    public Set<Option> getSupportedOptions() {
+        final Set<Option> options = new LinkedHashSet<>();
+        for (final Option op : super.getSupportedOptions()) {
+            if (op.getNames().contains("-d")) {
+                options.add(new Option() {
+                    @Override public int          getArgumentCount() {return op.getArgumentCount();}
+                    @Override public String       getDescription()   {return op.getDescription();}
+                    @Override public Option.Kind  getKind()          {return op.getKind();}
+                    @Override public List<String> getNames()         {return op.getNames();}
+                    @Override public String       getParameters()    {return op.getParameters();}
+                    @Override public boolean process(final String option, final List<String> arguments) {
+                        outputDirectory = arguments.get(0);
+                        return op.process(option, arguments);
+                    }
+                });
+            } else {
+                options.add(op);
             }
         }
-        final boolean success = HtmlDoclet.start(root);
+        return options;
+    }
+
+    /**
+     * Returns a name identifying this doclet.
+     *
+     * @return "ApacheSIS".
+     */
+    @Override
+    public String getName() {
+        return "ApacheSIS";
+    }
+
+    /**
+     * Invoked by Javadoc for starting the doclet.
+     *
+     * @param  environment  the Javadoc environment.
+     * @return {@code true} on success, or {@code false} on failure.
+     */
+    @Override
+    @SuppressWarnings("CallToPrintStackTrace")
+    public boolean run(final DocletEnvironment environment) {
+        final boolean success = super.run(environment);
         if (success && outputDirectory != null) try {
             final File output = new File(outputDirectory);
             final File customCSS = customCSS(output);
@@ -109,10 +170,14 @@ public final class Doclet extends HtmlDoclet {
                 }
             }
         } catch (IOException e) {
-            final StringWriter buffer = new StringWriter();
-            final PrintWriter p = new PrintWriter(buffer);
-            e.printStackTrace(p);
-            root.printError(buffer.toString());
+            if (reporter != null) {
+                final StringWriter buffer = new StringWriter();
+                final PrintWriter p = new PrintWriter(buffer);
+                e.printStackTrace(p);
+                reporter.print(Diagnostic.Kind.ERROR, buffer.toString());
+            } else {
+                e.printStackTrace();            // This fallback should not be needed, but we are paranoiac.
+            }
             return false;
         }
         return success;
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/Include.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Include.java
similarity index 75%
rename from core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/Include.java
rename to core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Include.java
index 03c0a30..3c6cc6a 100644
--- a/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/Include.java
+++ b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Include.java
@@ -14,13 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.internal.taglet;
+package org.apache.sis.internal.doclet;
 
 import java.io.*;
-import java.util.Map;
-import com.sun.javadoc.Tag;
-import com.sun.javadoc.SourcePosition;
-import com.sun.tools.doclets.Taglet;
+import com.sun.source.doctree.DocTree;
 
 
 /**
@@ -36,7 +33,7 @@ import com.sun.tools.doclets.Taglet;
  * just before the parts to copy in the javadoc.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.5
+ * @version 0.8
  * @since   0.5
  * @module
  */
@@ -52,26 +49,16 @@ public final class Include extends InlineTaglet {
     private static final String DOCUMENT_END = "</body>";
 
     /**
-     * Register this taglet.
-     *
-     * @param  tagletMap  the map to register this tag to.
-     */
-    public static void register(final Map<String,Taglet> tagletMap) {
-       final Include tag = new Include();
-       tagletMap.put(tag.getName(), tag);
-    }
-
-    /**
-     * Constructs a default <code>@include</code> taglet.
+     * Constructs an <code>@include</code> taglet.
      */
-    private Include() {
+    public Include() {
         super();
     }
 
     /**
      * Returns the name of this custom tag.
      *
-     * @return the tag name.
+     * @return "include".
      */
     @Override
     public String getName() {
@@ -79,21 +66,20 @@ public final class Include extends InlineTaglet {
     }
 
     /**
-     * Given the <code>Tag</code> representation of this custom tag, return its string representation.
+     * Given the <code>DocTree</code> representation of this custom tag, return its string representation.
      *
      * @param  tag  the tag to format.
      * @return a string representation of the given tag.
      */
     @Override
-    public String toString(final Tag tag) {
-        final SourcePosition position = tag.position();
-        final String reference = tag.text();
+    protected String toString(final DocTree tag) {
+        final String reference = text(tag);
         final int sep = reference.indexOf('#');
         if (sep < 0) {
-            printWarning(position, "@include expected a reference like \"filename#anchor\" but got \"" + reference + "\".");
+            printWarning(tag, "@include expected a reference like \"filename#anchor\" but got \"" + reference + "\".");
             return reference;
         }
-        File file = position.file();
+        File file = file(tag);
         file = new File(file.getParentFile(), reference.substring(0, sep));
         final String anchor = reference.substring(sep + 1);
         final StringBuilder buffer = new StringBuilder();
@@ -104,7 +90,7 @@ public final class Include extends InlineTaglet {
             String line;
             int start, end;
             do if ((line = in.readLine()) == null) {
-                printWarning(position, "Header \"" + anchor + "\" not found in file " + file);
+                printWarning(tag, "Header \"" + anchor + "\" not found in file " + file);
                 return reference;
             }
             while ((start = line.indexOf(ANCHOR_START)) < 0 ||
@@ -117,7 +103,7 @@ public final class Include extends InlineTaglet {
             while (true) {
                 line = in.readLine();
                 if (line == null) {
-                    printWarning(position, "Unexpected end of file in " + file);
+                    printWarning(tag, "Unexpected end of file in " + file);
                     return reference;
                 }
                 start = line.indexOf(ANCHOR_START);
@@ -130,7 +116,7 @@ public final class Include extends InlineTaglet {
                 buffer.append(line).append('\n');
             }
         } catch (IOException e) {
-            printError(position, "Error reading " + file + ":\n" + e);
+            printError(tag, "Error reading " + file + ":\n" + e);
         }
         return buffer.toString();
     }
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/InlineTaglet.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/InlineTaglet.java
new file mode 100644
index 0000000..7d220f6
--- /dev/null
+++ b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/InlineTaglet.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.doclet;
+
+import java.io.File;
+import java.util.Set;
+import java.util.EnumSet;
+import java.util.List;
+import javax.tools.Diagnostic;
+import javax.lang.model.element.Element;
+import jdk.javadoc.doclet.Reporter;
+import jdk.javadoc.doclet.Taglet;
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.TextTree;
+import com.sun.source.doctree.UnknownInlineTagTree;
+import com.sun.source.tree.CompilationUnitTree;
+import jdk.javadoc.doclet.DocletEnvironment;
+
+
+/**
+ * Base class of inline taglets.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 0.8
+ * @since   0.3
+ * @module
+ */
+abstract class InlineTaglet implements Taglet {
+    /**
+     * Where to report warnings, or {@code null} if unknown.
+     */
+    private Reporter reporter;
+
+    /**
+     * Constructs a default inline taglet.
+     */
+    InlineTaglet() {
+    }
+
+    /**
+     * Initializes this taglet with the given doclet environment and doclet.
+     *
+     * @param env     the environment in which the taglet is running.
+     * @param doclet  the doclet that instantiated this taglet.
+     */
+    @Override
+    public void init(final DocletEnvironment env, final jdk.javadoc.doclet.Doclet doclet) {
+        reporter = ((Doclet) doclet).reporter;
+    }
+
+    /**
+     * Returns the set of locations in which this taglet may be used.
+     * By default the taglet can be used everywhere.
+     *
+     * @return the set of locations in which this taglet may be used.
+     */
+    @Override
+    public Set<Taglet.Location> getAllowedLocations() {
+        return EnumSet.allOf(Taglet.Location.class);
+    }
+
+    /**
+     * Returns {@code true} since this base class is all about inline tags.
+     *
+     * @return always {@code true}.
+     */
+    @Override
+    public final boolean isInlineTag() {
+        return true;
+    }
+
+    /**
+     * Returns the text contained in the given inline tag.
+     */
+    static String text(final DocTree tag) {
+        for (final DocTree node : ((UnknownInlineTagTree) tag).getContent()) {
+            if (node.getKind() == DocTree.Kind.TEXT) {
+                return ((TextTree) node).getBody().trim();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * Returns the file that contains the given tag.
+     */
+    static File file(final DocTree tag) {
+        return new File(getCompilationUnitTree(tag).getSourceFile().getName());
+    }
+
+    private static CompilationUnitTree getCompilationUnitTree(final DocTree tree) {
+        throw new UnsupportedOperationException("We have not yet found how to get the compilation unit."); // TODO
+    }
+
+    /**
+     * Given a list of {@code DocTree}s representing this custom tag, returns its string representation.
+     * This method will be invoked once for each instance of the tag in parsed Javadoc.
+     *
+     * @param  tags     the tags to format.
+     * @param  element  the element to which the enclosing comment belongs.
+     * @return a string representation of the given tags.
+     */
+    @Override
+    public final String toString(final List<? extends DocTree> tags, final Element element) {
+        final StringBuilder buffer = new StringBuilder(64);
+        for (final DocTree tag : tags) {
+            buffer.append(toString(tag));
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Given a single {@code DocTree}s representing this custom tag, returns its string representation.
+     * This method will be invoked once for each instance of the tag in parsed Javadoc.
+     *
+     * @param  tag  the tag to format.
+     * @return a string representation of the given tag.
+     */
+    protected abstract String toString(DocTree tag);
+
+    /**
+     * Prints a warning message.
+     */
+    @SuppressWarnings("UseOfSystemOutOrSystemErr")
+    final void printWarning(final DocTree tag, final String message) {
+        if (reporter != null) {
+            reporter.print(Diagnostic.Kind.WARNING, message);
+        } else {
+            System.err.println(message);
+        }
+    }
+
+    /**
+     * Prints an error message.
+     */
+    @SuppressWarnings("UseOfSystemOutOrSystemErr")
+    final void printError(final DocTree tag, final String message) {
+        if (reporter != null) {
+            reporter.print(Diagnostic.Kind.ERROR, message);
+        } else {
+            System.err.println(message);
+        }
+    }
+}
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Module.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Module.java
new file mode 100644
index 0000000..276e09a
--- /dev/null
+++ b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Module.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.doclet;
+
+import java.io.File;
+import java.util.List;
+import java.util.Set;
+import java.util.EnumSet;
+import jdk.javadoc.doclet.Taglet;
+import com.sun.source.doctree.DocTree;
+import javax.lang.model.element.Element;
+
+
+/**
+ * The <code>@module</code> tag. This tag expects no argument.
+ *
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @version 0.8
+ * @since   0.3
+ * @module
+ */
+public final class Module implements Taglet {
+    /**
+     * The SIS module in which the <code>@module</code> taglet has been found.
+     */
+    private String module;
+
+    /**
+     * Constructs a <code>@module</code> taglet.
+     */
+    public Module() {
+        super();
+    }
+
+    /**
+     * Returns the name of this custom tag.
+     *
+     * @return "module".
+     */
+    @Override
+    public String getName() {
+        return "module";
+    }
+
+    /**
+     * Returns the set of locations in which this taglet may be used.
+     *
+     * @return the set of locations in which this taglet may be used.
+     */
+    @Override
+    public Set<Taglet.Location> getAllowedLocations() {
+        return EnumSet.of(Taglet.Location.PACKAGE,
+                          Taglet.Location.TYPE);
+    }
+
+    /**
+     * Returns {@code false} since <code>@module</code> is not an inline tag.
+     *
+     * @return always {@code false}.
+     */
+    @Override
+    public boolean isInlineTag() {
+        return false;
+    }
+
+    /**
+     * Given a list of {@code DocTree}s representing this custom tag, returns its string representation.
+     *
+     * @param  tags     the tags to format.
+     * @param  element  the element to which the enclosing comment belongs.
+     * @return a string representation of the given tags.
+     */
+    @Override
+    public String toString(final List<? extends DocTree> tags, final Element element) {
+        if (tags == null || tags.isEmpty()) {
+            return "";
+        }
+        final StringBuilder buffer = new StringBuilder(128);
+        buffer.append("\n<p><font size=\"-1\">");
+        for (final DocTree tag : tags) {
+            File file = InlineTaglet.file(tag);
+            module = file.getName();
+            while ((file = file.getParentFile()) != null) {
+                if (file.getName().equals("src")) {
+                    file = file.getParentFile();
+                    if (file != null) {
+                        module = file.getName();
+                    }
+                    break;
+                }
+            }
+            /*
+             * Appends the module link.
+             */
+            buffer.append("Defined in the <code>").append(module).append("</code> module");
+        }
+        return buffer.append("</font></p>\n").toString();
+    }
+}
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/Preformat.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Preformat.java
similarity index 86%
rename from core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/Preformat.java
rename to core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Preformat.java
index 335e6fe..c370054 100644
--- a/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/Preformat.java
+++ b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/Preformat.java
@@ -14,12 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.internal.taglet;
+package org.apache.sis.internal.doclet;
 
-import java.util.Map;
 import java.util.StringTokenizer;
-import com.sun.javadoc.Tag;
-import com.sun.tools.doclets.Taglet;
+import com.sun.source.doctree.DocTree;
 import org.apache.sis.internal.book.CodeColorizer;
 
 
@@ -31,10 +29,10 @@ import org.apache.sis.internal.book.CodeColorizer;
  *
  * <p>This taglet will automatically replace {@code &}, {@code <} and {@code >} by their HTML entities.
  * The only exception is {@code &#64;}, which is converted to the original {@code @} character because
- * we can't use that character directly inside this taglet.</p>
+ * we can not use that character directly inside this taglet.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 0.8
  * @since   0.3
  * @module
  */
@@ -59,26 +57,16 @@ public final class Preformat extends InlineTaglet {
     };
 
     /**
-     * Register this taglet.
-     *
-     * @param tagletMap the map to register this tag to.
-     */
-    public static void register(final Map<String,Taglet> tagletMap) {
-       final Preformat tag = new Preformat();
-       tagletMap.put(tag.getName(), tag);
-    }
-
-    /**
-     * Constructs a default <code>@preformat</code> taglet.
+     * Constructs a <code>@preformat</code> taglet.
      */
-    private Preformat() {
+    public Preformat() {
         super();
     }
 
     /**
      * Returns the name of this custom tag.
      *
-     * @return the tag name.
+     * @return "preformat".
      */
     @Override
     public String getName() {
@@ -86,24 +74,14 @@ public final class Preformat extends InlineTaglet {
     }
 
     /**
-     * Returns {@code false} since <code>@preformat</code> can not be used in overview.
-     *
-     * @return always {@code false}.
-     */
-    @Override
-    public boolean inOverview() {
-        return false;
-    }
-
-    /**
-     * Given the <code>Tag</code> representation of this custom tag, return its string representation.
+     * Given the <code>DocTree</code> representation of this custom tag, return its string representation.
      *
-     * @param tag The tag to format.
+     * @param  tag  the tag to format.
      * @return a string representation of the given tag.
      */
     @Override
-    public String toString(final Tag tag) {
-        String text = tag.text().trim().replace("\r\n", "\n").replace('\r', '\n');
+    protected String toString(final DocTree tag) {
+        String text = text(tag).replace("\r\n", "\n").replace('\r', '\n');
         String format = "<unspecified>";
         /*
          * Extracts the first word, which is expected to be the format name.
@@ -119,7 +97,7 @@ public final class Preformat extends InlineTaglet {
         try {
             style = Style.valueOf(format);
         } catch (IllegalArgumentException e) {
-            printWarning(tag.position(), "Unknown format: " + format);
+            printWarning(tag, "Unknown format: " + format);
             style = Style.text;
         }
         /*
@@ -148,7 +126,7 @@ all:    while (tk.hasMoreTokens()) {
         /*
          * Nows inserts each line.
          */
-        final StringBuilder buffer = new StringBuilder("<pre class=\"code-sample\">");
+        final StringBuilder buffer = new StringBuilder("<blockquote><pre>");
         tk = new StringTokenizer(text, "\r\n", true);
         while (tk.hasMoreTokens()) {
             String line = tk.nextToken();
@@ -166,7 +144,7 @@ all:    while (tk.hasMoreTokens()) {
             }
             buffer.append(line);
         }
-        return buffer.append("</pre>").toString();
+        return buffer.append("</pre></blockquote>").toString();
     }
 
     /**
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/package-info.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/package-info.java
index 179291e..22a22e4 100644
--- a/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/package-info.java
+++ b/core/sis-build-helper/src/main/java/org/apache/sis/internal/doclet/package-info.java
@@ -17,10 +17,11 @@
 
 
 /**
- * Doclet performing post-processing after Javadoc generation.
+ * Javadoc taglets for processing custom tags in SIS source code comments,
+ * together with doclet performing post-processing after Javadoc generation.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.5
  * @module
  */
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/InlineTaglet.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/InlineTaglet.java
deleted file mode 100644
index cc95022..0000000
--- a/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/InlineTaglet.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sis.internal.taglet;
-
-import com.sun.javadoc.Tag;
-import com.sun.javadoc.RootDoc;
-import com.sun.javadoc.SourcePosition;
-import com.sun.tools.doclets.Taglet;
-import com.sun.tools.doclets.internal.toolkit.Configuration;
-import com.sun.tools.doclets.formats.html.ConfigurationImpl;
-
-
-/**
- * Base class of inline taglets.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.3
- * @since   0.3
- * @module
- */
-abstract class InlineTaglet implements Taglet {
-    /**
-     * The doclet configuration, created when first needed for reporting warnings.
-     */
-    private static Configuration configuration;
-
-    /**
-     * Returns the root document, or {@code null} if none.
-     */
-    private static synchronized RootDoc getRootDoc() {
-        if (configuration == null) {
-            configuration = new ConfigurationImpl();
-        }
-        return configuration.root;
-    }
-
-    /**
-     * Constructs a default inline taglet.
-     */
-    InlineTaglet() {
-    }
-
-    /**
-     * Returns {@code true} since SIS taglets can be used in overview.
-     *
-     * @return default to {@code true}.
-     */
-    @Override
-    public boolean inOverview() {
-        return true;
-    }
-
-    /**
-     * Returns {@code true} since SIS taglets can be used in package documentation.
-     *
-     * @return default to {@code true}.
-     */
-    @Override
-    public boolean inPackage() {
-        return true;
-    }
-
-    /**
-     * Returns {@code true} since SIS taglets can be used in type documentation
-     * (classes or interfaces).
-     *
-     * @return default to {@code true}.
-     */
-    @Override
-    public boolean inType() {
-        return true;
-    }
-
-    /**
-     * Returns {@code true} since SIS taglets can be used in constructor
-     *
-     * @return default to {@code true}.
-     */
-    @Override
-    public boolean inConstructor() {
-        return true;
-    }
-
-    /**
-     * Returns {@code true} since SIS taglets can be used in method documentation.
-     *
-     * @return default to {@code true}.
-     */
-    @Override
-    public boolean inMethod() {
-        return true;
-    }
-
-    /**
-     * Returns {@code true} since SIS taglets can be used in field documentation.
-     *
-     * @return default to {@code true}.
-     */
-    @Override
-    public boolean inField() {
-        return true;
-    }
-
-    /**
-     * Returns {@code true} since this base class is all about inline tags.
-     *
-     * @return always {@code true}.
-     */
-    @Override
-    public final boolean isInlineTag() {
-        return true;
-    }
-
-    /**
-     * Given an array of {@code Tag}s representing this custom tag, return its string
-     * representation. This method should not be called since arrays of inline tags do
-     * not exist. However we define it as a matter of principle.
-     *
-     * @param  tags  the tags to format.
-     * @return a string representation of the given tags.
-     */
-    @Override
-    public final String toString(final Tag[] tags) {
-        final StringBuilder buffer = new StringBuilder(64);
-        for (int i=0; i<tags.length; i++) {
-            buffer.append(toString(tags[i]));
-        }
-        return buffer.toString();
-    }
-
-    /**
-     * Prints a warning message.
-     */
-    @SuppressWarnings("UseOfSystemOutOrSystemErr")
-    static void printWarning(final SourcePosition position, final String message) {
-        final RootDoc root = getRootDoc();
-        if (root != null) {
-            root.printWarning(position, message);
-        } else {
-            System.err.println(message);
-        }
-    }
-
-    /**
-     * Prints an error message.
-     */
-    @SuppressWarnings("UseOfSystemOutOrSystemErr")
-    static void printError(final SourcePosition position, final String message) {
-        final RootDoc root = getRootDoc();
-        if (root != null) {
-            root.printError(position, message);
-        } else {
-            System.err.println(message);
-        }
-    }
-}
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/Module.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/Module.java
deleted file mode 100644
index 536258d..0000000
--- a/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/Module.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sis.internal.taglet;
-
-import java.io.File;
-import java.util.Map;
-import com.sun.javadoc.Tag;
-import com.sun.tools.doclets.Taglet;
-
-
-/**
- * The <code>@module</code> tag. This tag expects no argument.
- *
- * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.4
- * @since   0.3
- * @module
- */
-public final class Module implements Taglet {
-    /**
-     * Register this taglet.
-     *
-     * @param  tagletMap  the map to register this tag to.
-     */
-    public static void register(final Map<String,Taglet> tagletMap) {
-       final Module tag = new Module();
-       tagletMap.put(tag.getName(), tag);
-    }
-
-    /**
-     * The SIS module in which the <code>@module</code> taglet has been found.
-     */
-    private String module;
-
-    /**
-     * Constructs a default <code>@module</code> taglet.
-     */
-    private Module() {
-        super();
-    }
-
-    /**
-     * Returns the name of this custom tag.
-     *
-     * @return the tag name.
-     */
-    @Override
-    public String getName() {
-        return "module";
-    }
-
-    /**
-     * Returns {@code false} since <code>@module</code> can not be used in overview.
-     *
-     * @return always {@code false}.
-     */
-    @Override
-    public boolean inOverview() {
-        return false;
-    }
-
-    /**
-     * Returns {@code true} since <code>@module</code> can be used in package documentation.
-     *
-     * @return always {@code true}.
-     */
-    @Override
-    public boolean inPackage() {
-        return true;
-    }
-
-    /**
-     * Returns {@code true} since <code>@module</code> can be used in type documentation
-     * (classes or interfaces). This is actually its main target.
-     *
-     * @return always {@code true}.
-     */
-    @Override
-    public boolean inType() {
-        return true;
-    }
-
-    /**
-     * Returns {@code false} since <code>@module</code> can not be used in constructor.
-     *
-     * @return always {@code false}.
-     */
-    @Override
-    public boolean inConstructor() {
-        return false;
-    }
-
-    /**
-     * Returns {@code false} since <code>@module</code> can not be used in method documentation.
-     *
-     * @return always {@code false}.
-     */
-    @Override
-    public boolean inMethod() {
-        return false;
-    }
-
-    /**
-     * Returns {@code false} since <code>@module</code> can not be used in field documentation.
-     *
-     * @return always {@code false}.
-     */
-    @Override
-    public boolean inField() {
-        return false;
-    }
-
-    /**
-     * Returns {@code false} since <code>@module</code> is not an inline tag.
-     *
-     * @return always {@code false}.
-     */
-    @Override
-    public boolean isInlineTag() {
-        return false;
-    }
-
-    /**
-     * Given the <code>Tag</code> representation of this custom tag, return its string representation.
-     * The default implementation invokes the array variant of this method.
-     *
-     * @param  tag  the tag to format.
-     * @return a string representation of the given tag.
-     */
-    @Override
-    public String toString(final Tag tag) {
-        return toString(new Tag[] {tag});
-    }
-
-    /**
-     * Given an array of {@code Tag}s representing this custom tag, return its string
-     * representation.
-     *
-     * @param  tags  the tags to format.
-     * @return a string representation of the given tags.
-     */
-    @Override
-    public String toString(final Tag[] tags) {
-        if (tags == null || tags.length == 0) {
-            return "";
-        }
-        final StringBuilder buffer = new StringBuilder(128);
-        buffer.append("\n<p><font size=\"-1\">");
-        for (final Tag tag : tags) {
-            File file = tag.position().file();
-            module = file.getName();
-            while ((file = file.getParentFile()) != null) {
-                if (file.getName().equals("src")) {
-                    file = file.getParentFile();
-                    if (file != null) {
-                        module = file.getName();
-                    }
-                    break;
-                }
-            }
-            /*
-             * Appends the module link.
-             */
-            buffer.append("Defined in the <code>").append(module).append("</code> module");
-        }
-        return buffer.append("</font></p>\n").toString();
-    }
-}
diff --git a/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/package-info.java b/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/package-info.java
deleted file mode 100644
index e8857ed..0000000
--- a/core/sis-build-helper/src/main/java/org/apache/sis/internal/taglet/package-info.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/**
- * Javadoc taglets for processing custom tags in SIS source code comments.
- *
- * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.3
- * @since   0.3
- * @module
- */
-package org.apache.sis.internal.taglet;
diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/RangeFormatTest.java b/core/sis-utility/src/test/java/org/apache/sis/measure/RangeFormatTest.java
index b87c675..0226cf2 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/measure/RangeFormatTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/measure/RangeFormatTest.java
@@ -322,11 +322,11 @@ public final strictfp class RangeFormatTest extends TestCase {
         String text = it.toString();
         findYears(it, RangeFormat.Field.MIN_VALUE, minPos);
         findYears(it, RangeFormat.Field.MAX_VALUE, maxPos);
-        assertEquals("[16/01/70 18:00 … 16/01/90 09:00]", text);
+        assertEquals("[16/01/1970 18:00 … 16/01/1990 09:00]", text);
         assertEquals( 7, minPos.getBeginIndex());
-        assertEquals( 9, minPos.getEndIndex());
-        assertEquals(24, maxPos.getBeginIndex());
-        assertEquals(26, maxPos.getEndIndex());
+        assertEquals(11, minPos.getEndIndex());
+        assertEquals(26, maxPos.getBeginIndex());
+        assertEquals(30, maxPos.getEndIndex());
         assertEquals(range, parse(text));
         /*
          * Try again with the infinity symbol in one endpoint.
@@ -335,18 +335,18 @@ public final strictfp class RangeFormatTest extends TestCase {
         it    = format.formatToCharacterIterator(range);
         text  = it.toString();
         findYears(it, RangeFormat.Field.MAX_VALUE, maxPos);
-        assertEquals("(−∞ … 01/01/90 00:00]", text);
+        assertEquals("(−∞ … 01/01/1990 00:00]", text);
         assertEquals(12, maxPos.getBeginIndex());
-        assertEquals(14, maxPos.getEndIndex());
+        assertEquals(16, maxPos.getEndIndex());
         assertEquals(range, parse(text));
 
         range = new Range<>(Date.class, new Date(20*YEAR), true, (Date) null, true);
         it    = format.formatToCharacterIterator(range);
         text  = it.toString();
         findYears(it, RangeFormat.Field.MIN_VALUE, minPos);
-        assertEquals("[01/01/90 00:00 … ∞)", text);
-        assertEquals(7, minPos.getBeginIndex());
-        assertEquals(9, minPos.getEndIndex());
+        assertEquals("[01/01/1990 00:00 … ∞)", text);
+        assertEquals( 7, minPos.getBeginIndex());
+        assertEquals(11, minPos.getEndIndex());
         assertEquals(range, parse(text));
     }
 
diff --git a/core/sis-utility/src/test/java/org/apache/sis/test/Assert.java b/core/sis-utility/src/test/java/org/apache/sis/test/Assert.java
index 34f9ce4..670f9a4 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/test/Assert.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/test/Assert.java
@@ -363,6 +363,7 @@ public strictfp class Assert extends org.opengis.test.Assert {
      * @return the deserialized object.
      */
     public static <T> T assertSerializedEquals(final T object) {
+        Objects.requireNonNull(object);
         final Object deserialized;
         try {
             final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@@ -381,7 +382,10 @@ public strictfp class Assert extends org.opengis.test.Assert {
         } catch (IOException e) {
             throw new AssertionError(e.toString(), e);
         }
-        // Compares with the original object and returns it.
+        assertNotNull("Deserialized object shall not be null.", deserialized);
+        /*
+         * Compare with the original object and return it.
+         */
         @SuppressWarnings("unchecked")
         final Class<? extends T> type = (Class<? extends T>) object.getClass();
         assertEquals("Deserialized object not equal to the original one.", object, deserialized);
diff --git a/ide-project/NetBeans/nbproject/build-impl.xml b/ide-project/NetBeans/nbproject/build-impl.xml
index 1f0a2f8..1fdcce1 100644
--- a/ide-project/NetBeans/nbproject/build-impl.xml
+++ b/ide-project/NetBeans/nbproject/build-impl.xml
@@ -19,7 +19,7 @@ is divided into following sections:
   - cleanup
 
         -->
-<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="Apache_SIS_on_GeoAPI_4.0-impl">
+<project xmlns:if="ant:if" xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" xmlns:unless="ant:unless" basedir=".." default="default" name="Apache_SIS_on_GeoAPI_4.0-impl">
     <fail message="Please build using Ant 1.8.0 or higher.">
         <condition>
             <not>
@@ -53,7 +53,72 @@ is divided into following sections:
         <property file="nbproject/configs/${config}.properties"/>
         <property file="nbproject/project.properties"/>
     </target>
-    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
+    <target name="-init-modules-supported">
+        <condition property="modules.supported.internal" value="true">
+            <not>
+                <matches pattern="1\.[0-8](\..*)?" string="${javac.source}"/>
+            </not>
+        </condition>
+    </target>
+    <target depends="-init-modules-supported" if="modules.supported.internal" name="-init-macrodef-modulename">
+        <macrodef name="modulename" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute name="property"/>
+            <attribute name="sourcepath"/>
+            <sequential>
+                <loadresource property="@{property}" quiet="true">
+                    <javaresource classpath="@{sourcepath}" name="module-info.java" parentFirst="false"/>
+                    <filterchain>
+                        <stripjavacomments/>
+                        <linecontainsregexp>
+                            <regexp pattern="module .* \{"/>
+                        </linecontainsregexp>
+                        <tokenfilter>
+                            <linetokenizer/>
+                            <replaceregex flags="s" pattern="(\s*module\s+)(\S*)(\s*\{.*)" replace="\2"/>
+                        </tokenfilter>
+                        <striplinebreaks/>
+                    </filterchain>
+                </loadresource>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-modules-supported,-init-macrodef-modulename" if="modules.supported.internal" name="-init-source-module-properties">
+        <fail message="Java 9 support requires Ant 1.10.0 or higher.">
+            <condition>
+                <not>
+                    <antversion atleast="1.10.0"/>
+                </not>
+            </condition>
+        </fail>
+        <j2seproject3:modulename property="module.name" sourcepath="${src.local-src.dir}:${src.webapp.dir}:${src.javafx.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.raster.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}"/>
+        <condition property="named.module.internal">
+            <and>
+                <isset property="module.name"/>
+                <length length="0" string="${module.name}" when="greater"/>
+            </and>
+        </condition>
+        <condition property="unnamed.module.internal">
+            <not>
+                <isset property="named.module.internal"/>
+            </not>
+        </condition>
+        <property name="javac.modulepath" value=""/>
+        <property name="run.modulepath" value="${javac.modulepath}"/>
+        <property name="module.build.classes.dir" value="${build.classes.dir}"/>
+        <property name="debug.modulepath" value="${run.modulepath}"/>
+        <property name="javac.upgrademodulepath" value=""/>
+        <property name="run.upgrademodulepath" value="${javac.upgrademodulepath}"/>
+        <condition else="" property="javac.systemmodulepath.cmd.line.arg" value="--system '${javac.systemmodulepath}'">
+            <and>
+                <isset property="javac.systemmodulepath"/>
+                <length length="0" string="${javac.systemmodulepath}" when="greater"/>
+            </and>
+        </condition>
+        <property name="dist.jlink.dir" value="${dist.dir}/jlink"/>
+        <property name="dist.jlink.output" value="${dist.jlink.dir}/${application.title}"/>
+        <property name="module.name" value=""/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property,-init-modules-supported" name="-do-init">
         <property name="platform.java" value="${java.home}/bin/java"/>
         <available file="${manifest.file}" property="manifest.available"/>
         <condition property="splashscreen.available">
@@ -76,7 +141,9 @@ is divided into following sections:
             <and>
                 <isset property="javac.profile"/>
                 <length length="0" string="${javac.profile}" when="greater"/>
-                <matches pattern="((1\.[89])|9)(\..*)?" string="${javac.source}"/>
+                <not>
+                    <matches pattern="1\.[0-7](\..*)?" string="${javac.source}"/>
+                </not>
             </and>
         </condition>
         <condition property="do.archive">
@@ -94,6 +161,9 @@ is divided into following sections:
                 <not>
                     <istrue value="${mkdist.disabled}"/>
                 </not>
+                <not>
+                    <istrue value="${modules.supported.internal}"/>
+                </not>
             </and>
         </condition>
         <condition property="do.archive+manifest.available">
@@ -326,11 +396,80 @@ is divided into following sections:
             </sequential>
         </macrodef>
     </target>
-    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
+    <target depends="-init-ap-cmdline-properties,-init-source-module-properties" if="modules.supported.internal" name="-init-macrodef-javac-with-module">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.local-src.dir}:${src.webapp.dir}:${src.javafx.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.raster.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.modulepath}" name="modulepath"/>
+            <attribute default="${javac.upgrademodulepath}" name="upgrademodulepath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${javac.processormodulepath}" name="processormodulepath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath" unless:set="named.module.internal"/>
+            <attribute default="${src.local-src.dir}:${src.webapp.dir}:${src.javafx.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.raster.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}" if:set="named.module.internal" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <condition property="warn.excludes.internal">
+                    <and>
+                        <isset property="named.module.internal"/>
+                        <length length="0" string="@{excludes}" trim="true" when="greater"/>
+                    </and>
+                </condition>
+                <echo if:set="warn.excludes.internal" level="warning" message="The javac excludes are not supported in the JDK 9 Named Module."/>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <mkdir dir="@{apgeneratedsrcdir}"/>
+                <condition property="processormodulepath.set">
+                    <resourcecount count="0" when="greater">
+                        <path>
+                            <pathelement path="@{processormodulepath}"/>
+                        </path>
+                    </resourcecount>
+                </condition>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <modulepath>
+                        <path path="@{modulepath}"/>
+                    </modulepath>
+                    <upgrademodulepath>
+                        <path path="@{upgrademodulepath}"/>
+                    </upgrademodulepath>
+                    <compilerarg line="${javac.systemmodulepath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <compilerarg if:set="processormodulepath.set" value="--processor-module-path"/>
+                    <compilerarg if:set="processormodulepath.set" path="@{processormodulepath}"/>
+                    <compilerarg unless:set="processormodulepath.set" value="-processorpath"/>
+                    <compilerarg path="@{processorpath}:${empty.dir}" unless:set="processormodulepath.set"/>
+                    <compilerarg line="${ap.processors.internal}"/>
+                    <compilerarg line="${annotation.processing.processor.options}"/>
+                    <compilerarg value="-s"/>
+                    <compilerarg path="@{apgeneratedsrcdir}"/>
+                    <compilerarg line="${ap.proc.none.internal}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-source-module-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors" unless="modules.supported.internal">
         <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
             <attribute default="${src.local-src.dir}:${src.webapp.dir}:${src.javafx.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.raster.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}" name="srcdir"/>
             <attribute default="${build.classes.dir}" name="destdir"/>
             <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.modulepath}" name="modulepath"/>
+            <attribute default="${javac.upgrademodulepath}" name="upgrademodulepath"/>
             <attribute default="${javac.processorpath}" name="processorpath"/>
             <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
             <attribute default="${includes}" name="includes"/>
@@ -367,11 +506,13 @@ is divided into following sections:
             </sequential>
         </macrodef>
     </target>
-    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+    <target depends="-init-ap-cmdline-properties,-init-source-module-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
         <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
             <attribute default="${src.local-src.dir}:${src.webapp.dir}:${src.javafx.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.raster.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}" name="srcdir"/>
             <attribute default="${build.classes.dir}" name="destdir"/>
             <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.modulepath}" name="modulepath"/>
+            <attribute default="${javac.upgrademodulepath}" name="upgrademodulepath"/>
             <attribute default="${javac.processorpath}" name="processorpath"/>
             <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
             <attribute default="${includes}" name="includes"/>
@@ -400,7 +541,7 @@ is divided into following sections:
             </sequential>
         </macrodef>
     </target>
-    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+    <target depends="-init-macrodef-javac-with-module,-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
         <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
             <attribute default="${src.local-src.dir}:${src.webapp.dir}:${src.javafx.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.raster.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}" name="srcdir"/>
             <attribute default="${build.classes.dir}" name="destdir"/>
@@ -455,113 +596,153 @@ is divided into following sections:
         <property name="test.binarytestincludes" value=""/>
         <property name="test.binaryexcludes" value=""/>
     </target>
-    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
-        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+    <target depends="-init-modules-supported" if="modules.supported.internal" name="-init-macrodef-junit-prototype-with-module">
+        <macrodef name="junit-prototype" uri="http://www.netbeans.org/ns/j2se-project/3">
             <attribute default="${includes}" name="includes"/>
             <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element name="customize" optional="true"/>
+            <element name="customizePrototype" optional="true"/>
             <sequential>
                 <property name="junit.forkmode" value="perTest"/>
                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
-                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
                     <syspropertyset>
                         <propertyref prefix="test-sys-prop."/>
                         <mapper from="test-sys-prop.*" to="*" type="glob"/>
                     </syspropertyset>
+                    <classpath>
+                        <path path="${run.test.classpath}"/>
+                    </classpath>
+                    <modulepath>
+                        <path path="${run.test.modulepath}"/>
+                    </modulepath>
                     <formatter type="brief" usefile="false"/>
                     <formatter type="xml"/>
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
                     <jvmarg value="-ea"/>
-                    <customize/>
+                    <jvmarg line="${run.test.jvmargs}"/>
+                    <customizePrototype/>
                 </junit>
             </sequential>
         </macrodef>
     </target>
-    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
-        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+    <target depends="-init-modules-supported" name="-init-macrodef-junit-prototype-without-module" unless="modules.supported.internal">
+        <macrodef name="junit-prototype" uri="http://www.netbeans.org/ns/j2se-project/3">
             <attribute default="${includes}" name="includes"/>
             <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element name="customize" optional="true"/>
+            <element name="customizePrototype" optional="true"/>
             <sequential>
                 <property name="junit.forkmode" value="perTest"/>
                 <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
-                    <batchtest todir="${build.test.results.dir}">
-                        <fileset dir="${test.webapp.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.javafx.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.console.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.portrayal.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.earth-obs.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.geotiff.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.netcdf.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.shapefile.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.sql.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.xmlstore.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.storage.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.feature.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.raster.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.referencing.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.ref-by-id.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.metadata.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.utility.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.fra-profile.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.gdal.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
-                            <filename name="${test.binarytestincludes}"/>
-                        </fileset>
-                    </batchtest>
                     <syspropertyset>
                         <propertyref prefix="test-sys-prop."/>
                         <mapper from="test-sys-prop.*" to="*" type="glob"/>
                     </syspropertyset>
+                    <classpath>
+                        <path path="${run.test.classpath}"/>
+                    </classpath>
                     <formatter type="brief" usefile="false"/>
                     <formatter type="xml"/>
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
                     <jvmarg value="-ea"/>
-                    <customize/>
+                    <customizePrototype/>
                 </junit>
             </sequential>
         </macrodef>
     </target>
+    <target depends="-init-test-properties,-init-macrodef-junit-prototype-with-module,-init-macrodef-junit-prototype-without-module" if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit-prototype>
+                    <customizePrototype>
+                        <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                        <customize/>
+                    </customizePrototype>
+                </j2seproject3:junit-prototype>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties,-init-macrodef-junit-prototype-with-module,-init-macrodef-junit-prototype-without-module" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit-prototype>
+                    <customizePrototype>
+                        <batchtest todir="${build.test.results.dir}">
+                            <fileset dir="${test.webapp.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.javafx.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.console.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.portrayal.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.earth-obs.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.geotiff.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.netcdf.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.shapefile.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.sql.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.xmlstore.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.storage.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.feature.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.raster.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.referencing.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.ref-by-id.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.metadata.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.utility.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.fra-profile.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${test.gdal.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                                <filename name="${test.binarytestincludes}"/>
+                            </fileset>
+                        </batchtest>
+                        <customize/>
+                    </customizePrototype>
+                </j2seproject3:junit-prototype>
+            </sequential>
+        </macrodef>
+    </target>
     <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
     <target if="${testng.available}" name="-init-macrodef-testng">
         <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">
@@ -640,6 +821,10 @@ is divided into following sections:
                         <propertyref prefix="test-sys-prop."/>
                         <mapper from="test-sys-prop.*" to="*" type="glob"/>
                     </propertyset>
+                    <classpath>
+                        <path path="${run.test.classpath}"/>
+                    </classpath>
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
                     <customize/>
                 </testng>
             </sequential>
@@ -694,10 +879,6 @@ is divided into following sections:
             <sequential>
                 <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
                     <customize>
-                        <classpath>
-                            <path path="${run.test.classpath}"/>
-                        </classpath>
-                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
                         <jvmarg line="${run.jvmargs}"/>
                         <jvmarg line="${run.jvmargs.ide}"/>
                     </customize>
@@ -705,128 +886,20 @@ is divided into following sections:
             </sequential>
         </macrodef>
     </target>
-    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
-        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <property name="junit.forkmode" value="perTest"/>
-                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
-                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
-                    <syspropertyset>
-                        <propertyref prefix="test-sys-prop."/>
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
-                    </syspropertyset>
-                    <formatter type="brief" usefile="false"/>
-                    <formatter type="xml"/>
-                    <jvmarg value="-ea"/>
-                    <jvmarg line="${debug-args-line}"/>
-                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
-                    <customize/>
-                </junit>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
-        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <property name="junit.forkmode" value="perTest"/>
-                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
-                    <batchtest todir="${build.test.results.dir}">
-                        <fileset dir="${test.webapp.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.javafx.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.console.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.portrayal.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.earth-obs.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.geotiff.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.netcdf.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.shapefile.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.sql.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.xmlstore.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.storage.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.feature.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.raster.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.referencing.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.ref-by-id.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.metadata.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.utility.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.fra-profile.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${test.gdal.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
-                            <filename name="${test.binarytestincludes}"/>
-                        </fileset>
-                    </batchtest>
-                    <syspropertyset>
-                        <propertyref prefix="test-sys-prop."/>
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
-                    </syspropertyset>
-                    <formatter type="brief" usefile="false"/>
-                    <formatter type="xml"/>
-                    <jvmarg value="-ea"/>
-                    <jvmarg line="${debug-args-line}"/>
-                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
-                    <customize/>
-                </junit>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
         <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
             <attribute default="${includes}" name="includes"/>
             <attribute default="${excludes}" name="excludes"/>
             <attribute default="**" name="testincludes"/>
             <attribute default="" name="testmethods"/>
-            <element implicit="true" name="customize" optional="true"/>
+            <element name="customizeDebuggee" optional="true"/>
             <sequential>
-                <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
-                    <customize/>
-                </j2seproject3:junit-debug>
+                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <jvmarg value="-agentlib:jdwp=transport=${debug-transport},address=${jpda.address}"/>
+                        <customizeDebuggee/>
+                    </customize>
+                </j2seproject3:junit>
             </sequential>
         </macrodef>
     </target>
@@ -845,14 +918,14 @@ is divided into following sections:
                 <delete dir="${build.test.results.dir}" quiet="true"/>
                 <mkdir dir="${build.test.results.dir}"/>
                 <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">
-                    <customize>
+                    <customizeDebuggee>
                         <customize2/>
                         <jvmarg value="-ea"/>
                         <arg line="${testng.debug.mode}"/>
                         <arg line="-d ${build.test.results.dir}"/>
                         <arg line="-listener org.testng.reporters.VerboseReporter"/>
                         <arg line="${testng.cmd.args}"/>
-                    </customize>
+                    </customizeDebuggee>
                 </j2seproject3:debug>
             </sequential>
         </macrodef>
@@ -879,14 +952,10 @@ is divided into following sections:
             <attribute default="" name="testMethod"/>
             <sequential>
                 <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
-                    <customize>
-                        <classpath>
-                            <path path="${run.test.classpath}"/>
-                        </classpath>
-                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <customizeDebuggee>
                         <jvmarg line="${run.jvmargs}"/>
                         <jvmarg line="${run.jvmargs.ide}"/>
-                    </customize>
+                    </customizeDebuggee>
                 </j2seproject3:test-debug-impl>
             </sequential>
         </macrodef>
@@ -966,10 +1035,14 @@ is divided into following sections:
     <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
         <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
             <attribute default="${main.class}" name="name"/>
+            <attribute default="${debug.modulepath}" name="modulepath"/>
             <attribute default="${debug.classpath}" name="classpath"/>
             <attribute default="" name="stopclassname"/>
             <sequential>
                 <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
+                    <modulepath>
+                        <path path="@{modulepath}"/>
+                    </modulepath>
                     <classpath>
                         <path path="@{classpath}"/>
                     </classpath>
@@ -988,18 +1061,6 @@ is divided into following sections:
         </macrodef>
     </target>
     <target name="-init-debug-args">
-        <property name="version-output" value="java version &quot;${ant.java.version}"/>
-        <condition property="have-jdk-older-than-1.4">
-            <or>
-                <contains string="${version-output}" substring="java version &quot;1.0"/>
-                <contains string="${version-output}" substring="java version &quot;1.1"/>
-                <contains string="${version-output}" substring="java version &quot;1.2"/>
-                <contains string="${version-output}" substring="java version &quot;1.3"/>
-            </or>
-        </condition>
-        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
-            <istrue value="${have-jdk-older-than-1.4}"/>
-        </condition>
         <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
             <os family="windows"/>
         </condition>
@@ -1009,21 +1070,79 @@ is divided into following sections:
     </target>
     <target depends="-init-debug-args" name="-init-macrodef-debug">
         <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${module.name}" name="modulename"/>
             <attribute default="${main.class}" name="classname"/>
+            <attribute default="${debug.modulepath}" name="modulepath"/>
             <attribute default="${debug.classpath}" name="classpath"/>
+            <element name="customizeDebuggee" optional="true"/>
+            <sequential>
+                <j2seproject1:java classname="@{classname}" classpath="@{classpath}" modulename="@{modulename}" modulepath="@{modulepath}">
+                    <customize>
+                        <jvmarg value="-agentlib:jdwp=transport=${debug-transport},address=${jpda.address}"/>
+                        <customizeDebuggee/>
+                    </customize>
+                </j2seproject1:java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-source-module-properties" if="named.module.internal" name="-init-macrodef-java-with-module">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${module.name}" name="modulename"/>
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${run.modulepath}" name="modulepath"/>
+            <attribute default="${run.upgrademodulepath}" name="upgrademodulepath"/>
+            <attribute default="${run.classpath}" name="classpath"/>
+            <attribute default="jvm" name="jvm"/>
             <element name="customize" optional="true"/>
             <sequential>
-                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
-                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
-                    <jvmarg line="${debug-args-line}"/>
-                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true" module="@{modulename}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <modulepath>
+                        <pathelement path="@{modulepath}"/>
+                        <pathelement location="${module.build.classes.dir}"/>
+                    </modulepath>
+                    <upgrademodulepath>
+                        <path path="@{upgrademodulepath}"/>
+                    </upgrademodulepath>
                     <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
                     <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
                     <jvmarg line="${run.jvmargs}"/>
                     <jvmarg line="${run.jvmargs.ide}"/>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-source-module-properties" if="unnamed.module.internal" name="-init-macrodef-java-with-unnamed-module">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="" name="modulename"/>
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${run.modulepath}" name="modulepath"/>
+            <attribute default="${run.upgrademodulepath}" name="upgrademodulepath"/>
+            <attribute default="${run.classpath}" name="classpath"/>
+            <attribute default="jvm" name="jvm"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
                     <classpath>
                         <path path="@{classpath}"/>
                     </classpath>
+                    <modulepath>
+                        <path path="@{modulepath}"/>
+                    </modulepath>
+                    <upgrademodulepath>
+                        <path path="@{upgrademodulepath}"/>
+                    </upgrademodulepath>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
                     <syspropertyset>
                         <propertyref prefix="run-sys-prop."/>
                         <mapper from="run-sys-prop.*" to="*" type="glob"/>
@@ -1033,9 +1152,11 @@ is divided into following sections:
             </sequential>
         </macrodef>
     </target>
-    <target name="-init-macrodef-java">
+    <target depends="-init-source-module-properties" name="-init-macrodef-java-without-module" unless="modules.supported.internal">
         <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="" name="modulename"/>
             <attribute default="${main.class}" name="classname"/>
+            <attribute default="" name="modulepath"/>
             <attribute default="${run.classpath}" name="classpath"/>
             <attribute default="jvm" name="jvm"/>
             <element name="customize" optional="true"/>
@@ -1058,6 +1179,7 @@ is divided into following sections:
             </sequential>
         </macrodef>
     </target>
+    <target depends="-init-macrodef-java-with-module, -init-macrodef-java-with-unnamed-module, -init-macrodef-java-without-module" name="-init-macrodef-java"/>
     <target name="-init-macrodef-copylibs">
         <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
             <attribute default="${manifest.file}" name="manifest"/>
@@ -1148,6 +1270,7 @@ is divided into following sections:
             <param name="call.target" value="jar"/>
             <param name="transfer.built-jar.properties" value="${built-jar.properties}"/>
             <param name="transfer.not.archive.disabled" value="true"/>
+            <param name="transfer.do.jlink" value="false"/>
         </antcall>
     </target>
     <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
@@ -1155,7 +1278,9 @@ is divided into following sections:
         <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
     </target>
     <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
-        <antcall target="clean"/>
+        <antcall target="clean">
+            <param name="no.dependencies" value="true"/>
+        </antcall>
     </target>
     <target depends="init,deps-jar" name="-pre-pre-compile">
         <mkdir dir="${build.classes.dir}"/>
@@ -1216,7 +1341,7 @@ is divided into following sections:
     <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
         <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
         <j2seproject3:force-recompile/>
-        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.local-src.dir}:${src.webapp.dir}:${src.javafx.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.raster.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile. [...]
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}, module-info.java" sourcepath="${src.local-src.dir}:${src.webapp.dir}:${src.javafx.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.raster.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}: [...]
     </target>
     <target name="-post-compile-single">
         <!-- Empty placeholder for easier customization. -->
@@ -1236,6 +1361,25 @@ is divided into following sections:
         <!-- Empty placeholder for easier customization. -->
         <!-- You can override this target in the ../build.xml file. -->
     </target>
+    <target depends="init,compile" name="-check-module-main-class">
+        <pathconvert property="main.class.file">
+            <string value="${main.class}"/>
+            <unpackagemapper from="*" to="*.class"/>
+        </pathconvert>
+        <condition property="do.module.main.class">
+            <and>
+                <isset property="main.class.available"/>
+                <available file="${build.classes.dir}/module-info.class"/>
+                <available file="${build.classes.dir}/${main.class.file}"/>
+                <isset property="libs.CopyLibs.classpath"/>
+                <available classname="org.netbeans.modules.java.j2seproject.moduletask.ModuleMainClass" classpath="${libs.CopyLibs.classpath}"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-check-module-main-class" if="do.module.main.class" name="-set-module-main-class">
+        <taskdef classname="org.netbeans.modules.java.j2seproject.moduletask.ModuleMainClass" classpath="${libs.CopyLibs.classpath}" name="modulemainclass"/>
+        <modulemainclass failonerror="false" mainclass="${main.class}" moduleinfo="${build.classes.dir}/module-info.class"/>
+    </target>
     <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available">
         <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
         <touch file="${tmp.manifest.file}" verbose="false"/>
@@ -1272,11 +1416,37 @@ is divided into following sections:
         <j2seproject1:jar manifest="${tmp.manifest.file}"/>
         <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
         <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <condition else="${dist.jar.resolved}" property="jar.usage.message.class.path.replacement" value="">
+            <isset property="named.module.internal"/>
+        </condition>
         <pathconvert property="run.classpath.with.dist.jar">
             <path path="${run.classpath}"/>
+            <map from="${build.classes.dir.resolved}" to="${jar.usage.message.class.path.replacement}"/>
+        </pathconvert>
+        <pathconvert property="run.modulepath.with.dist.jar">
+            <path location="${dist.jar.resolved}"/>
+            <path path="${run.modulepath}"/>
             <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
         </pathconvert>
-        <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java} -cp ${run.classpath.with.dist.jar} ${main.class}">
+        <condition else="${run.modulepath}" property="jar.usage.message.run.modulepath.with.dist.jar" value="${run.modulepath.with.dist.jar}">
+            <isset property="named.module.internal"/>
+        </condition>
+        <condition else="" property="jar.usage.message.module.path" value=" -p ${jar.usage.message.run.modulepath.with.dist.jar}">
+            <and>
+                <isset property="modules.supported.internal"/>
+                <length length="0" string="${jar.usage.message.run.modulepath.with.dist.jar}" when="greater"/>
+            </and>
+        </condition>
+        <condition else="" property="jar.usage.message.class.path" value=" -cp ${run.classpath.with.dist.jar}">
+            <length length="0" string="${run.classpath.with.dist.jar}" when="greater"/>
+        </condition>
+        <condition else="/${main.class}" property="jar.usage.message.main.class.class.selector" value="">
+            <isset property="do.module.main.class"/>
+        </condition>
+        <condition else=" ${main.class}" property="jar.usage.message.main.class" value=" -m ${module.name}${jar.usage.message.main.class.class.selector}">
+            <isset property="named.module.internal"/>
+        </condition>
+        <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java}${jar.usage.message.module.path}${jar.usage.message.class.path}${jar.usage.message.main.class}">
             <isset property="main.class.available"/>
         </condition>
         <condition else="debug" property="jar.usage.level" value="info">
@@ -1295,8 +1465,73 @@ is divided into following sections:
         <!-- Empty placeholder for easier customization. -->
         <!-- You can override this target in the ../build.xml file. -->
     </target>
-    <target depends="init,compile,-pre-jar,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>
-    <target depends="init,compile,-pre-jar,-do-jar,-post-jar" description="Build JAR." name="jar"/>
+    <target depends="init,compile,-pre-jar,-set-module-main-class,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>
+    <target depends="init,compile,-pre-jar,-do-jar,-post-jar,deploy" description="Build JAR." name="jar"/>
+    <!--
+                =================
+                DEPLOY SECTION
+                =================
+            -->
+    <target name="-pre-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init" name="-check-jlink">
+        <condition property="do.jlink.internal">
+            <and>
+                <istrue value="${do.jlink}"/>
+                <isset property="do.archive"/>
+                <isset property="named.module.internal"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="init,-do-jar,-post-jar,-pre-deploy,-check-jlink" if="do.jlink.internal" name="-do-deploy">
+        <delete dir="${dist.jlink.dir}" failonerror="false" quiet="true"/>
+        <property name="jlink.launcher.name" value="${application.title}"/>
+        <condition else="${module.name}" property="jlink.add.modules" value="${module.name},${jlink.additionalmodules}">
+            <and>
+                <isset property="jlink.additionalmodules"/>
+                <length length="0" string="${jlink.additionalmodules}" when="greater"/>
+            </and>
+        </condition>
+        <condition property="jlink.do.strip.internal">
+            <and>
+                <isset property="jlink.strip"/>
+                <istrue value="${jlink.strip}"/>
+            </and>
+        </condition>
+        <condition property="jlink.do.additionalparam.internal">
+            <and>
+                <isset property="jlink.additionalparam"/>
+                <length length="0" string="${jlink.additionalparam}" when="greater"/>
+            </and>
+        </condition>
+        <condition property="jlink.do.launcher.internal">
+            <and>
+                <istrue value="${jlink.launcher}"/>
+                <isset property="main.class.available"/>
+            </and>
+        </condition>
+        <property name="platform.jlink" value="${jdk.home}/bin/jlink"/>
+        <property name="jlink.systemmodules.internal" value="${jdk.home}/jmods"/>
+        <exec executable="${platform.jlink}">
+            <arg value="--module-path"/>
+            <arg path="${jlink.systemmodules.internal}:${run.modulepath}:${dist.jar}"/>
+            <arg value="--add-modules"/>
+            <arg value="${jlink.add.modules}"/>
+            <arg if:set="jlink.do.strip.internal" value="--strip-debug"/>
+            <arg if:set="jlink.do.launcher.internal" value="--launcher"/>
+            <arg if:set="jlink.do.launcher.internal" value="${jlink.launcher.name}=${module.name}/${main.class}"/>
+            <arg if:set="jlink.do.additionalparam.internal" line="${jlink.additionalparam}"/>
+            <arg value="--output"/>
+            <arg value="${dist.jlink.output}"/>
+        </exec>
+    </target>
+    <target name="-post-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-do-jar,-post-jar,-pre-deploy,-do-deploy,-post-deploy" name="deploy"/>
     <!--
                 =================
                 EXECUTION SECTION
@@ -1333,9 +1568,9 @@ is divided into following sections:
     </target>
     <target depends="init,compile" name="-debug-start-debuggee">
         <j2seproject3:debug>
-            <customize>
+            <customizeDebuggee>
                 <arg line="${application.args}"/>
-            </customize>
+            </customizeDebuggee>
         </j2seproject3:debug>
     </target>
     <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
@@ -1401,28 +1636,24 @@ is divided into following sections:
             </customize>
         </profile>
     </target>
-    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
+    <target depends="-init-macrodef-junit,profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
         <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
         <nbprofiledirect>
             <classpath>
                 <path path="${run.test.classpath}"/>
             </classpath>
         </nbprofiledirect>
-        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
-            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
-            <jvmarg value="${profiler.info.jvmargs.agent}"/>
-            <jvmarg line="${profiler.info.jvmargs}"/>
-            <test name="${profile.class}"/>
-            <classpath>
-                <path path="${run.test.classpath}"/>
-            </classpath>
-            <syspropertyset>
-                <propertyref prefix="test-sys-prop."/>
-                <mapper from="test-sys-prop.*" to="*" type="glob"/>
-            </syspropertyset>
-            <formatter type="brief" usefile="false"/>
-            <formatter type="xml"/>
-        </junit>
+        <j2seproject3:junit excludes="${excludes}" includes="${includes}" testincludes="${profile.class}" testmethods="">
+            <customize>
+                <jvmarg value="-agentlib:jdwp=transport=${debug-transport},address=${jpda.address}"/>
+                <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+                <jvmarg value="${profiler.info.jvmargs.agent}"/>
+                <jvmarg line="${profiler.info.jvmargs}"/>
+                <classpath>
+                    <path path="${run.test.classpath}"/>
+                </classpath>
+            </customize>
+        </j2seproject3:junit>
     </target>
     <!--
                 end of pre NB72 profiling section
@@ -1478,6 +1709,12 @@ is divided into following sections:
         <condition else="" property="bug5101868workaround" value="*.java">
             <matches pattern="1\.[56](\..*)?" string="${java.version}"/>
         </condition>
+        <condition else="" property="javadoc.html5.cmd.line.arg" value="-html5">
+            <and>
+                <isset property="javadoc.html5"/>
+                <available file="${jdk.home}${file.separator}lib${file.separator}jrt-fs.jar"/>
+            </and>
+        </condition>
         <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version} [...]
             <classpath>
                 <path path="${javac.classpath}"/>
@@ -1550,6 +1787,7 @@ is divided into following sections:
                 <exclude name="*.java"/>
             </fileset>
             <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
+            <arg line="${javadoc.html5.cmd.line.arg}"/>
         </javadoc>
         <copy todir="${dist.javadoc.dir}">
             <fileset dir="${src.local-src.dir}" excludes="${excludes}" includes="${includes}">
@@ -1636,11 +1874,63 @@ is divided into following sections:
         <!-- Empty placeholder for easier customization. -->
         <!-- You can override this target in the ../build.xml file. -->
     </target>
+    <target depends="-init-source-module-properties" if="named.module.internal" name="-init-test-javac-module-properties-with-module">
+        <j2seproject3:modulename property="test.module.name" sourcepath="${test.webapp.dir}:${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.raster.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.gdal.dir}"/>
+        <condition else="${empty.dir}" property="javac.test.sourcepath" value="${test.webapp.dir}:${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.raster.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.gdal.dir}">
+            <and>
+                <isset property="test.module.name"/>
+                <length length="0" string="${test.module.name}" when="greater"/>
+            </and>
+        </condition>
+        <condition else="--patch-module ${module.name}=${test.webapp.dir}:${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.raster.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.gdal.dir} --add-reads ${module.name}=ALL-UNNAMED" property=" [...]
+            <and>
+                <isset property="test.module.name"/>
+                <length length="0" string="${test.module.name}" when="greater"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-init-source-module-properties" if="named.module.internal" name="-init-test-run-module-properties">
+        <condition else="${module.name}" property="run.test.addexport.source.module.internal" value="${test.module.name}">
+            <and>
+                <isset property="test.module.name"/>
+                <length length="0" string="${test.module.name}" when="greater"/>
+            </and>
+        </condition>
+        <fileset dir="${build.test.classes.dir}" id="run.test.packages.internal" includes="**/*.class"/>
+        <property location="${build.test.classes.dir}" name="build.test.classes.dir.abs.internal"/>
+        <pathconvert pathsep=" " property="run.test.addexports.internal" refid="run.test.packages.internal">
+            <chainedmapper>
+                <regexpmapper from="^(.*)\Q${file.separator}\E.*\.class$$" to="\1"/>
+                <filtermapper>
+                    <uniqfilter/>
+                    <replacestring from="${build.test.classes.dir.abs.internal}" to=""/>
+                </filtermapper>
+                <cutdirsmapper dirs="1"/>
+                <packagemapper from="*" to="--add-exports ${run.test.addexport.source.module.internal}/*=ALL-UNNAMED"/>
+            </chainedmapper>
+        </pathconvert>
+        <condition else="--patch-module ${module.name}=${build.test.classes.dir} --add-modules ${module.name} --add-reads ${module.name}=ALL-UNNAMED ${run.test.addexports.internal}" property="run.test.jvmargs" value="--add-modules ${test.module.name} --add-reads ${test.module.name}=ALL-UNNAMED ${run.test.addexports.internal}">
+            <and>
+                <isset property="test.module.name"/>
+                <length length="0" string="${test.module.name}" when="greater"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-init-source-module-properties" name="-init-test-module-properties-without-module" unless="named.module.internal">
+        <property name="javac.test.sourcepath" value="${empty.dir}"/>
+        <property name="javac.test.compilerargs" value=""/>
+        <property name="run.test.jvmargs" value=""/>
+    </target>
+    <target depends="-init-test-javac-module-properties-with-module,-init-test-module-properties-without-module" name="-init-test-module-properties"/>
     <target if="do.depend.true" name="-compile-test-depend">
         <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.webapp.dir}:${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.raster.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.gdal.dir}"/>
     </target>
-    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
-        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir="${test.webapp.dir}:${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.raster.dir}:${test.referencing.dir [...]
+    <target depends="init,deps-jar,compile,-init-test-module-properties,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${javac.test.sourcepath}" srcdir="${test.webapp.dir}:${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${tes [...]
+            <customize>
+                <compilerarg line="${javac.test.compilerargs}"/>
+            </customize>
+        </j2seproject3:javac>
         <copy todir="${build.test.classes.dir}">
             <fileset dir="${test.webapp.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
             <fileset dir="${test.javafx.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
@@ -1672,10 +1962,14 @@ is divided into following sections:
         <!-- Empty placeholder for easier customization. -->
         <!-- You can override this target in the ../build.xml file. -->
     </target>
-    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
+    <target depends="init,deps-jar,compile,-init-test-module-properties,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
         <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
         <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
-        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="${test.webapp.dir}:${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.d [...]
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}, module-info.java" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${test.webapp.dir}:${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:$ [...]
+            <customize>
+                <compilerarg line="${javac.test.compilerargs}"/>
+            </customize>
+        </j2seproject3:javac>
         <copy todir="${build.test.classes.dir}">
             <fileset dir="${test.webapp.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
             <fileset dir="${test.javafx.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
@@ -1711,7 +2005,7 @@ is divided into following sections:
     <target depends="init" if="have.tests" name="-pre-test-run">
         <mkdir dir="${build.test.results.dir}"/>
     </target>
-    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
+    <target depends="init,compile-test,-init-test-run-module-properties,-pre-test-run" if="have.tests" name="-do-test-run">
         <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>
     </target>
     <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
@@ -1723,14 +2017,14 @@ is divided into following sections:
     <target depends="init" if="have.tests" name="-pre-test-run-single">
         <mkdir dir="${build.test.results.dir}"/>
     </target>
-    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
+    <target depends="init,compile-test-single,-init-test-run-module-properties,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
         <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
         <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
     </target>
     <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
         <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
     </target>
-    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+    <target depends="init,compile-test-single,-init-test-run-module-properties,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
     <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
         <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
         <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
@@ -1739,7 +2033,7 @@ is divided into following sections:
     <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
         <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
     </target>
-    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
+    <target depends="init,compile-test-single,-init-test-run-module-properties,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
     <!--
                 =======================
                 TEST DEBUGGING SECTION
@@ -1757,8 +2051,8 @@ is divided into following sections:
     <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
         <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
     </target>
-    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
-    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+    <target depends="init,compile-test-single,-init-test-run-module-properties,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+    <target depends="init,compile-test-single,-init-test-run-module-properties,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
     <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
         <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
     </target>
@@ -1784,9 +2078,9 @@ is divided into following sections:
     <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
         <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
         <j2seproject3:debug classname="sun.applet.AppletViewer">
-            <customize>
+            <customizeDebuggee>
                 <arg value="${applet.url}"/>
-            </customize>
+            </customizeDebuggee>
         </j2seproject3:debug>
     </target>
     <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
@@ -1817,10 +2111,12 @@ is divided into following sections:
             <param name="call.target" value="clean"/>
             <param name="transfer.built-clean.properties" value="${built-clean.properties}"/>
             <param name="transfer.not.archive.disabled" value="true"/>
+            <param name="transfer.do.jlink" value="false"/>
         </antcall>
     </target>
     <target depends="init" name="-do-clean">
         <delete dir="${build.dir}"/>
+        <delete dir="${dist.jlink.output}"/>
         <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
     </target>
     <target name="-post-clean">
diff --git a/ide-project/NetBeans/nbproject/genfiles.properties b/ide-project/NetBeans/nbproject/genfiles.properties
index ec32b8a..af88b83 100644
--- a/ide-project/NetBeans/nbproject/genfiles.properties
+++ b/ide-project/NetBeans/nbproject/genfiles.properties
@@ -4,5 +4,5 @@ build.xml.data.CRC32=58e6b21c
 build.xml.script.CRC32=462eaba0
 build.xml.stylesheet.CRC32=28e38971@1.53.1.46
 nbproject/build-impl.xml.data.CRC32=40d83d59
-nbproject/build-impl.xml.script.CRC32=b7ab89c5
-nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48
+nbproject/build-impl.xml.script.CRC32=a7689f96
+nbproject/build-impl.xml.stylesheet.CRC32=3a2fa800@1.88.0.48
diff --git a/ide-project/NetBeans/nbproject/project.properties b/ide-project/NetBeans/nbproject/project.properties
index e3f775c..953d168 100644
--- a/ide-project/NetBeans/nbproject/project.properties
+++ b/ide-project/NetBeans/nbproject/project.properties
@@ -35,8 +35,8 @@ project.license      = apache20
 project.licensePath  = ../LicenseHeader.txt
 no.dependencies      = true
 source.encoding      = UTF-8
-javac.source         = 1.8
-javac.target         = 1.8
+javac.source         = 9
+javac.target         = 9
 platform.active      = default_platform
 junit.forkmode       = once
 run.jvmargs          = -ea -Dorg.apache.sis.test.verbose=true -Dorg.apache.sis.test.extensive=true
@@ -142,6 +142,7 @@ javac.classpath=\
     ${maven.repository}/org/osgi/org.osgi.core/${osgi.version}/org.osgi.core-${osgi.version}.jar:\
     ${maven.repository}/org/postgresql/postgresql/${postgresql.version}/postgresql-${postgresql.version}.jar:\
     ${maven.repository}/com/googlecode/jaxb-namespaceprefixmapper-interfaces/JAXBNamespacePrefixMapper/${jaxb-ns-mapper}/JAXBNamespacePrefixMapper-${jaxb-ns-mapper}.jar
+javac.modulepath=
 javac.processorpath=\
     ${javac.classpath}
 javac.test.classpath=\
@@ -156,11 +157,17 @@ javac.test.classpath=\
     ${build.classes.dir}
 javac.test.processorpath=\
     ${javac.test.classpath}
+javac.processormodulepath=\
+    ${javac.modulepath}
+javac.test.modulepath=\
+    ${javac.modulepath}
 run.classpath=\
     ${javac.classpath}:\
     ${build.classes.dir}:\
     ${maven.repository}/org/apache/derby/derby/${derby.version}/derby-${derby.version}.jar:\
     ${maven.repository}/org/webjars/material-design-icons/${icons.version}/material-design-icons-${icons.version}.jar
+run.modulepath=\
+    ${javac.modulepath}
 run.test.classpath=\
     ${javac.test.classpath}:\
     ${build.test.classes.dir}:\
@@ -173,10 +180,16 @@ run.test.classpath=\
     ${maven.repository}/org/apache/httpcomponents/httpclient/${httpclient.version}/httpclient-${httpclient.version}.jar:\
     ${maven.repository}/org/slf4j/slf4j-api/${slf4j.version}/slf4j-api-${slf4j.version}.jar:\
     ${maven.repository}/org/slf4j/slf4j-jdk14/${slf4j.version}/slf4j-jdk14-${slf4j.version}.jar
+run.test.modulepath=\
+    ${javac.test.modulepath}
 debug.classpath=\
     ${run.classpath}
+debug.modulepath=\
+    ${run.modulepath}
 debug.test.classpath=\
     ${run.test.classpath}
+debug.test.modulepath=\
+    ${run.test.modulepath}
 
 #
 # Module paths (can be used as a replacement for classpaths on JDK 9).
@@ -197,7 +210,8 @@ debug.test.modulepath=\
 #
 # Build configuration and destination directories.
 #
-javac.compilerargs                       = -Xdoclint:syntax,html,reference,missing/protected,accessibility/protected
+javac.compilerargs                       = --add-modules java.xml.bind,java.xml.ws.annotation,javafx.graphics \
+                                           -Xdoclint:syntax,html,reference,missing/protected,accessibility/protected
 javac.deprecation                        = true
 javac.external.vm                        = false
 javadoc.html5                            = true
@@ -244,6 +258,8 @@ dist.dir                                 = dist
 dist.jar                                 = ${dist.dir}/SIS.jar
 dist.javadoc.dir                         = ${dist.dir}/javadoc
 mkdist.disabled                          = true
+jlink.launcher                           = false
+jlink.launcher.name                      = ApacheSIS
 
 #
 # Editor
diff --git a/pom.xml b/pom.xml
index e8558c9..e50191e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -510,8 +510,8 @@
     <website.locale>en</website.locale>
 
     <!-- Following properties are branch-specific -->
-    <maven.compile.source>1.8</maven.compile.source>
-    <maven.compile.target>1.8</maven.compile.target>
+    <maven.compile.source>9</maven.compile.source>
+    <maven.compile.target>9</maven.compile.target>
     <sis.plugin.version>${project.version}</sis.plugin.version>
     <sis.non-free.version>0.8</sis.non-free.version>
     <geoapi.version>4.0-SNAPSHOT</geoapi.version>
@@ -527,35 +527,6 @@
       </properties>
     </profile>
 
-    <!-- Cross-version compilation (to be removed with JDK9). -->
-    <profile>
-      <id>bootclasspath</id>
-      <activation>
-        <property>
-          <name>bootclasspath</name>
-        </property>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <artifactId>maven-compiler-plugin</artifactId>
-            <configuration>
-              <compilerArgs>
-                <arg>-bootclasspath</arg>
-                <arg>${bootclasspath}</arg>
-              </compilerArgs>
-            </configuration>
-          </plugin>
-          <plugin>
-            <artifactId>maven-javadoc-plugin</artifactId>
-            <configuration>
-              <bootclasspath>${bootclasspath}</bootclasspath>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-
     <!-- ===================================================================
            If the user has not set the SIS_DATA environment variable, set a
            default value where we can create a minimalist database.
@@ -603,6 +574,7 @@
           <compilerArgs>
             <arg>-Xlint:all</arg>
             <arg>-Xdoclint:syntax,html,missing/protected,accessibility/protected</arg>
+            <arg>--add-modules</arg> <arg>java.xml.bind,java.xml.ws.annotation,javafx.graphics</arg>
             <arg>-h</arg> <arg>${project.build.sourceDirectory}/../c</arg>
           </compilerArgs>
         </configuration>