diff --git a/etc/spack/defaults/packages.yaml b/etc/spack/defaults/packages.yaml
index 2c91b75e45d68545a4ebc302372df00e7ca4577d..dcfbf76b51b715d67d4bb101cd1886c3c08a3af0 100644
--- a/etc/spack/defaults/packages.yaml
+++ b/etc/spack/defaults/packages.yaml
@@ -40,6 +40,7 @@ packages:
       opencl: [pocl]
       pil: [py-pillow]
       pkgconfig: [pkgconf, pkg-config]
+      rpc: [libtirpc]
       scalapack: [netlib-scalapack]
       sycl: [hipsycl]
       szip: [libszip, libaec]
diff --git a/var/spack/repos/builtin/packages/gdal/package.py b/var/spack/repos/builtin/packages/gdal/package.py
index 88075f8a4e11d3ec7c4140ed64aa228fb1aef628..5aafdb44a1a7a86b548a6b6a88d424c4031baca1 100644
--- a/var/spack/repos/builtin/packages/gdal/package.py
+++ b/var/spack/repos/builtin/packages/gdal/package.py
@@ -297,8 +297,8 @@ def configure_args(self):
         if '+hdf4' in spec:
             args.append('--with-hdf4={0}'.format(spec['hdf'].prefix))
             hdf4 = self.spec['hdf']
-            if '+libtirpc' in hdf4:
-                libs.append('-ltirpc')
+            if '+external-xdr' in hdf4 and hdf4['rpc'].name != 'libc':
+                libs.append(hdf4['rpc'].libs.link_flags)
         else:
             args.append('--with-hdf4=no')
 
diff --git a/var/spack/repos/builtin/packages/hdf/disable_doclint.patch b/var/spack/repos/builtin/packages/hdf/disable_doclint.patch
new file mode 100644
index 0000000000000000000000000000000000000000..221d8c77c6cfb0c14ad994f1414c9fdfea0e59b8
--- /dev/null
+++ b/var/spack/repos/builtin/packages/hdf/disable_doclint.patch
@@ -0,0 +1,11 @@
+--- a/java/src/Makefile.in
++++ b/java/src/Makefile.in
+@@ -818,7 +818,7 @@ $(jarfile): classhdf_java.stamp classes docs
+ .PHONY: docs classes
+ 
+ docs:
+-	$(JAVADOC) -sourcepath $(srcdir) -d javadoc -use -splitIndex -windowtitle $(WINDOWTITLE) -doctitle $(DOCTITLE) -J-Xmx180m -verbose -overview $(top_srcdir)/java/src/hdf/overview.html -classpath $(CLASSPATH_ENV) hdf.hdflib
++	$(JAVADOC) -sourcepath $(srcdir) -d javadoc -use -splitIndex -windowtitle $(WINDOWTITLE) -doctitle $(DOCTITLE) -J-Xmx180m -verbose -overview $(top_srcdir)/java/src/hdf/overview.html -classpath $(CLASSPATH_ENV) hdf.hdflib -Xdoclint:none
+ 
+ clean:
+ 	rm -rf $(JAVAROOT)/*
diff --git a/var/spack/repos/builtin/packages/hdf/package.py b/var/spack/repos/builtin/packages/hdf/package.py
index 67c2744470c055a332100fded7d0b7018441e8dd..d3076b35f9ac50eae3661e3252d7fed6acba84bd 100644
--- a/var/spack/repos/builtin/packages/hdf/package.py
+++ b/var/spack/repos/builtin/packages/hdf/package.py
@@ -15,45 +15,138 @@ class Hdf(AutotoolsPackage):
     list_url = "https://support.hdfgroup.org/ftp/HDF/releases/"
     list_depth = 2
 
+    version('4.2.15', sha256='dbeeef525af7c2d01539906c28953f0fdab7dba603d1bc1ec4a5af60d002c459')
     version('4.2.14', sha256='2d383e87c8a0ca6a5352adbd1d5546e6cc43dc21ff7d90f93efa644d85c0b14a')
     version('4.2.13', sha256='be9813c1dc3712c2df977d4960e1f13f20f447dfa8c3ce53331d610c1f470483')
     version('4.2.12', sha256='dd419c55e85d1a0e13f3ea5ed35d00710033ccb16c85df088eb7925d486e040c')
     version('4.2.11', sha256='c3f7753b2fb9b27d09eced4d2164605f111f270c9a60b37a578f7de02de86d24')
 
     variant('szip', default=False, description="Enable szip support")
-    variant('libtirpc', default=False, description="Use xdr library from libtirpc package; if false, will use system or hdf internal")
+    variant('external-xdr', default=True,
+            description="Use an external XDR backend")
+    variant('netcdf', default=False,
+            description='Build NetCDF API (version 2.3.2)')
+    variant('fortran', default=False,
+            description='Enable Fortran interface')
+    variant('java', default=False,
+            description='Enable Java JNI interface')
+    variant('shared', default=False, description='Enable shared library')
+    variant('pic', default=True,
+            description='Produce position-independent code')
 
-    depends_on('jpeg@6b:')
-    depends_on('szip', when='+szip')
-    depends_on('libtirpc', when='+libtirpc')
     depends_on('zlib@1.1.4:')
+    depends_on('jpeg')
+    depends_on('szip', when='+szip')
+    depends_on('rpc', when='+external-xdr')
 
     depends_on('bison', type='build')
     depends_on('flex',  type='build')
+    depends_on('java@7:', when='+java', type=('build', 'run'))
+
+    # https://forum.hdfgroup.org/t/cant-build-hdf-4-2-14-with-jdk-11-and-enable-java/5702
+    patch('disable_doclint.patch', when='@:4.2.14^java@9:')
+
+    conflicts('^libjpeg@:6a')
+
+    # configure: error: Cannot build shared fortran libraries.
+    # Please configure with --disable-fortran flag.
+    conflicts('+fortran', when='+shared')
+
+    # configure: error: Java requires shared libraries to be built
+    conflicts('+java', when='~shared')
+
+    # configure: WARNING: unrecognized options: --enable-java
+    conflicts('+java', when='@:4.2.11')
+
+    # The Java interface library uses netcdf-related macro definitions even
+    # when netcdf is disabled and the macros are not defined, e.g.:
+    # hdfsdsImp.c:158:30: error: 'MAX_NC_NAME' undeclared
+    conflicts('+java', when='@4.2.12:4.2.13~netcdf')
+
+    # TODO: '@:4.2.14 ~external-xdr' and the fact that we compile for 64 bit
+    #  architecture should be in conflict
+
+    @property
+    def libs(self):
+        """HDF can be queried for the following parameters:
+
+        - "shared": shared libraries (default if '+shared')
+        - "static": static libraries (default if '~shared')
+        - "transitive": append transitive dependencies to the list of static
+            libraries (the argument is ignored if shared libraries are
+            requested)
+
+        :return: list of matching libraries
+        """
+        libraries = ['libmfhdf', 'libdf']
+
+        query_parameters = self.spec.last_query.extra_parameters
+
+        if 'shared' in query_parameters:
+            shared = True
+        elif 'static' in query_parameters:
+            shared = False
+        else:
+            shared = '+shared' in self.spec
+
+        libs = find_libraries(
+            libraries, root=self.prefix, shared=shared, recursive=True
+        )
+
+        if not libs:
+            msg = 'Unable to recursively locate {0} {1} libraries in {2}'
+            raise spack.error.NoLibrariesError(
+                msg.format('shared' if shared else 'static',
+                           self.spec.name,
+                           self.spec.prefix))
+
+        if not shared and 'transitive' in query_parameters:
+            libs += self.spec['jpeg:transitive'].libs
+            libs += self.spec['zlib:transitive'].libs
+            if '+szip' in self.spec:
+                libs += self.spec['szip:transitive'].libs
+            if ('+external-xdr' in self.spec and
+                    self.spec['rpc'].name != 'libc'):
+                libs += self.spec['rpc:transitive'].libs
+
+        return libs
+
+    def flag_handler(self, name, flags):
+        if '+pic' in self.spec:
+            if name == 'cflags':
+                flags.append(self.compiler.cc_pic_flag)
+            elif name == 'fflags':
+                flags.append(self.compiler.f77_pic_flag)
+
+        return flags, None, None
 
     def configure_args(self):
-        spec = self.spec
-
-        config_args = [
-            'CFLAGS={0}'.format(self.compiler.cc_pic_flag),
-            '--with-jpeg={0}'.format(spec['jpeg'].prefix),
-            '--with-zlib={0}'.format(spec['zlib'].prefix),
-            '--disable-netcdf',  # must be disabled to build NetCDF with HDF4
-            '--enable-fortran',
-            '--disable-shared',  # fortran and shared libs are not compatible
-            '--enable-static',
-            '--enable-production'
-        ]
-
-        # Szip support
-        if '+szip' in spec:
-            config_args.append('--with-szlib={0}'.format(spec['szip'].prefix))
+        config_args = ['--enable-production',
+                       '--enable-static',
+                       '--with-zlib=%s' % self.spec['zlib'].prefix,
+                       '--with-jpeg=%s' % self.spec['jpeg'].prefix]
+
+        config_args += self.enable_or_disable('shared')
+        config_args += self.enable_or_disable('netcdf')
+        config_args += self.enable_or_disable('fortran')
+        config_args += self.enable_or_disable('java')
+
+        if '+szip' in self.spec:
+            config_args.append('--with-szlib=%s' % self.spec['szip'].prefix)
         else:
             config_args.append('--without-szlib')
 
-        if '+libtirpc' in spec:
-            config_args.append('LIBS=-ltirpc')
-            config_args.append('CPPFLAGS=-I{0}/include/tirpc'.format(
-                spec['libtirpc'].prefix))
-
+        if '~external-xdr' in self.spec:
+            config_args.append('--enable-hdf4-xdr')
+        elif self.spec['rpc'].name != 'libc':
+            # We should not specify '--disable-hdf4-xdr' due to a bug in the
+            # configure script.
+            config_args.append('LIBS=%s' % self.spec['rpc'].libs.link_flags)
         return config_args
+
+    # Otherwise, we randomly get:
+    # SDgetfilename:
+    #   incorrect file being opened - expected <file755>, retrieved <file754>
+    def check(self):
+        with working_dir(self.build_directory):
+            make('check', parallel=False)
diff --git a/var/spack/repos/builtin/packages/libc/package.py b/var/spack/repos/builtin/packages/libc/package.py
index a4fa9ac3a64c08b774871827bdfb906ac0adc403..e328c40ea1fe7e6f3356091d98b6831c5ec40a0b 100644
--- a/var/spack/repos/builtin/packages/libc/package.py
+++ b/var/spack/repos/builtin/packages/libc/package.py
@@ -7,13 +7,16 @@
 
 
 class Libc(Package):
-    """Dummy libc package to provide `iconv` virtual package"""
+    """Dummy package to provide interfaces available in libc."""
 
     homepage = "https://en.wikipedia.org/wiki/C_standard_library"
-    url      = ""
     has_code = False
     phases = []
 
     version('1.0')  # Dummy
-    variant('iconv', default=False, description='Set to True if libc provides iconv')
+
+    variant('iconv', default=False, description='Provides interfaces for Localization Functions')
+    variant('rpc', default=False, description='Provides interfaces for RPC')
+
     provides('iconv', when='+iconv')
+    provides('rpc', when='+rpc')
diff --git a/var/spack/repos/builtin/packages/libtirpc/package.py b/var/spack/repos/builtin/packages/libtirpc/package.py
index e6ce06e0ea02e22745499060eff501a3262e2784..f83c7499a098798ac3158fa4aec0d7bca7fcbfa0 100644
--- a/var/spack/repos/builtin/packages/libtirpc/package.py
+++ b/var/spack/repos/builtin/packages/libtirpc/package.py
@@ -15,6 +15,8 @@ class Libtirpc(AutotoolsPackage):
 
     version('1.1.4', sha256='2ca529f02292e10c158562295a1ffd95d2ce8af97820e3534fe1b0e3aec7561d')
 
+    provides('rpc')
+
     # FIXME: build error on macOS
     # auth_none.c:81:9: error: unknown type name 'mutex_t'
 
diff --git a/var/spack/repos/builtin/packages/netcdf-c/package.py b/var/spack/repos/builtin/packages/netcdf-c/package.py
index 153a1057b172c672255af5af8fcbf25bfda3fdb9..6043e1122d765d37f99cc6c68b130215cdba3c75 100644
--- a/var/spack/repos/builtin/packages/netcdf-c/package.py
+++ b/var/spack/repos/builtin/packages/netcdf-c/package.py
@@ -75,7 +75,7 @@ def url_for_version(self, version):
     depends_on('libtool', type='build', when='@4.7.0')
 
     depends_on("m4", type='build')
-    depends_on("hdf", when='+hdf4')
+    depends_on("hdf~netcdf", when='+hdf4')
 
     # curl 7.18.0 or later is required:
     # http://www.unidata.ucar.edu/software/netcdf/docs/getting_and_building_netcdf.html
@@ -219,9 +219,8 @@ def configure_args(self):
             if '+szip' in hdf4:
                 # This should also come from hdf4.libs
                 libs.append('-lsz')
-            if '+libtirpc' in hdf4:
-                # This should also come from hdf4.libs
-                libs.append('-ltirpc')
+            if '+external-xdr' in hdf4 and hdf4['rpc'].name != 'libc':
+                libs.append(hdf4['rpc'].libs.link_flags)
 
         # Fortran support
         # In version 4.2+, NetCDF-C and NetCDF-Fortran have split.