manifold-systems / manifold

Manifold is a Java compiler plugin, its features include Metaprogramming, Properties, Extension Methods, Operator Overloading, Templates, a Preprocessor, and more.
http://manifold.systems/
Apache License 2.0
2.41k stars 125 forks source link

Maven configuration hard to find and incomplete #469

Closed mfnalex closed 1 year ago

mfnalex commented 1 year ago

The example pom available at https://github.com/manifold-systems/manifold/tree/master/manifold-core-parent/manifold#maven does not mention that it's required to use the maven-shade-plugin to include the whole manifold classes. If it's not mentioned, I expect that it's not required to shade any of it.

For example using the manifold-ext dependency with provided (or with the default compile scope, without using the maven-shade-plugin) simply throws a ClassNotFoundException referring to manifold.rt.api.IBootstrap class.

The official docs should mention that shading is required. In fact, the whole docs require improvements imho - it took me quite a long time to actually find the required maven-compiler-plugin configuration in the first place - shouldn't it be mentioned (or at least linked) on the root README.md?

rsmckinney commented 1 year ago

Hi @mfnalex. Sorry to hear you're having trouble configuring manifold. Let's get you on the right track.

First, the build configuration for manifold core does not require the shade plugin. None of manifold, including manifold-ext, require it.

Manifold consists of a core project and several subprojects each having one or more modules. All manifold subprojects follow the same readme.md format; each has a section entitled Setup, which covers Maven and Gradle. For instance, if you are using manifold-ext, please follow the maven build configuration for that subproject as documented in Setup.

If you still have questions, please provide more information about your build config and environment, it will help diagnose what is going wrong. Thanks.

mfnalex commented 1 year ago

Hi, thanks for the quick reply.

the build configuration for manifold core does not require the shade plugin. None of manifold, including manifold-ext, require it.

I cannot confirm this. Not using maven-shade-plugin causes a NoClassDefFoundError. Steps to reproduce:

  1. Clone this project, which uses exactly the pom.xml from the Setup page you linked: https://github.com/mfnalex/ManifoldTest
  2. mvn package it
  3. Run the Main class using java -cp my-ext-app-0.1-SNAPSHOT.jar test.Main

As expected, it throws a NoClassDefFoundError as it inserts a call to IBootstrap#dasBoot() into every class' static init block:

mfnal@Jaegermeister MINGW64 ~/IdeaProjects/ManifoldTest/target (master)
$ java -cp my-ext-app-0.1-SNAPSHOT.jar test.Main
Exception in thread "main" java.lang.NoClassDefFoundError: manifold/rt/api/IBootstrap
        at test.Main.<clinit>(Main.java:3)
Caused by: java.lang.ClassNotFoundException: manifold.rt.api.IBootstrap
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 1 more

I'm not sure which further information you need about my build config and environment, please let me know and I'll add those missing details.

rsmckinney commented 1 year ago

@mfnalex Your classpath is missing the jars your project depends on.

-cp my-ext-app-0.1-SNAPSHOT.jar

A Mavan packaged jar has your project's compiled classes in it, nothing more. This is just how Maven/Gradle work. As such, the classpath must include runtime dependencies your project declares. In your case this means manifold-ext-rt.jar, manifold-rt.jar, and manifold-util.jar must be included in the classpath.

java -cp <your-packaged-jar>;<your-m2-repo>/manifold-ext-rt-2023.1.13.jar;<your-m2-repo>/manifold-rt-2023.1.13.jar;<your-m2-repo>/manifold-util-2023.1.13.jar test.Main

mfnalex commented 1 year ago

I know, that's why people usually use the maven-shade-plugin. So the manifold classes indeed need to be shaded or added to the classpath, which wasn't exactly clear from the example setup. Thanks for the clarification.

rsmckinney commented 1 year ago

Well, the shade plugin exists primarily to avoid jar conflicts by repackaging a dependency using a different package name. You are using shade to unpackage all the dependency jars your project uses and repackage them into an "uber" jar, which is fine if you aren't using modules/JPMS, your project is not a library, and there are no package conflicts.

In any case, this is common knowledge if one is familiar with the shade plugin and understands what a maven package consists of, which is why manifold docs don't cover this topic.

mfnalex commented 1 year ago

I would have assumed that it works like lombok, which does not require anything to be added to the classpath (except at compile time, obviously). It's not really obvious at all that manifold works like this imho.

rsmckinney commented 1 year ago

Yes, I can see your point of view, a lot of lombok users are beginning to use manifold. But unlike lombok, depending on what features of manifold you use, you may or may not need runtime dependencies; they are small, but required in some cases such as manifold-ext. The setup docs are pretty clear about that and provide maven/gradle scripts. The docs assume that the corresponding runtime classpath is understood as it is bog standard stuff. Perhaps we'll add more docs in this area. Thanks for pointing that out.