Inserting a single module-info after shading

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Inserting a single module-info after shading

Mark Raynsford
Hello!

I'm trying to embed and relocate some dependencies in a jar file with
the maven-shade-plugin. I have a trivial example here that does this:

  https://github.com/io7m/resolver-shade-example

The compilation produces a com.io7m.resolver-0.0.1-embedded.jar file
containing most of the dependencies except for a couple that I'd like
the user to provide (logback, slf4j). All of the included dependencies
are relocated to a package starting with "com.io7m.resolver.internal".

The problem: I now want to insert a module-info.java file that exports
only the com.io7m.resolver package (hiding the internal packages). I
can't put this file in the source tree itself because then the IDE will
complain endlessly that I've not "required" the external dependency
packages. This is correct, but the compiler obviously can't know that
by the time the jar is produced, all of those external packages will
actually be internal to the module (due to shading) and therefore
"requires" clauses are not... required.

What's the recommended way to deal with this? The intended final
module-info.java file is pretty trivial:

  module com.io7m.resolver {
    requires org.slf4j;
    exports com.io7m.resolver;
  }

It seems like I'd need to compile the module-info.java against a fake
source directory (to stop the compiler complaining that the module is
empty) and then insert the resulting module-info.class file into the
shaded jar file afterwards. This seems fairly ugly though. Is there a
better way?

--
Mark Raynsford | http://www.io7m.com


attachment0 (235 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Inserting a single module-info after shading

Mark Raynsford
On 2018-02-03T13:43:18 +0000
Mark Raynsford <[hidden email]> wrote:
>
> It seems like I'd need to compile the module-info.java against a fake
> source directory (to stop the compiler complaining that the module is
> empty) and then insert the resulting module-info.class file into the
> shaded jar file afterwards. This seems fairly ugly though. Is there a
> better way?

Actually, ignore my question!

I have hacked together something using the truezip-maven-plugin and
a separate compiler plugin execution to compile a module-info.java
file as described.

Unfortunately, the resulting jar doesn't run when executed as a modular
jar, presumably due to internal classloading and reflection hacks on the
part of the Maven and Resolver APIs:

Exception in thread "main"
com.io7m.resolver.internal.org.eclipse.aether.resolution.ArtifactResolutionException:
Could not transfer artifact com.google.guava:guava:jar:null from/to
central (https://repo.maven.apache.org/maven2/):
java.lang.IllegalAccessException: class
com.io7m.resolver.internal.org.apache.http.impl.client.CloseableHttpResponseProxy
(in module com.io7m.resolver) cannot access class
com.sun.proxy.jdk.proxy1.$Proxy0 (in module jdk.proxy1) because module
jdk.proxy1 does not export com.sun.proxy.jdk.proxy1 to module
com.io7m.resolver

I suspect this approach simply cannot work.

--
Mark Raynsford | http://www.io7m.com


attachment0 (235 bytes) Download Attachment