Placing and Unplacing in JAR Artifacts
The entire process of packaging EO objects and atoms into JAR artifacts
is explained in this blog post:
Objectionary: Dictionary and Factory for EO Objects.
It’s pretty straight forward. However, there is one tricky situation
related to placing compiled Java binaries into the JAR. This process
may go wrong and sometimes it does. In version 0.24.0 of
our Maven plugin we
introduced a pair of options for the unplace goal. Here is how they work.
First, when you build a JAR artifact in your Maven project, you have some .eo
sources in src/main/eo and some Java sources in src/main/java. They both
are compiled into .class files into target/classes.
Second, in order for your program to work, it needs .eo files for objects,
which it finds in Objectionary. The files
are “pulled” and then saved into target/eo/04-pull. Then, they also
are compiled into .class binaries and also placed into target/classes,
mixing together with your files.
Third, your program needs .class binaries from inside JAR artifacts,
which some .eo objects point to by means of +rt meta. The artifacts
are downloaded, unpacked, and then placed into target/classes.
Finally, it’s time to package your own JAR and release it to Maven Central.
Obviously, we don’t want all the files. previously placed into target/classes,
to be packaged into the JAR. We only want those that were compiled from your
source .java files. We don’t even want those .class files that were
compiled from the auto-generated .java from your .eo objects.
We only want compiled atoms to be in the JAR.
The Maven plugin goal unplace cleans up the target/classes directory and
removes unnecessary binaries, which were placed into it earlier. It understands
which files to remove, thanks to the catalog it maintains during the entire
build cycle, in target/eo/placed.csv file. The goal unspile adds more
cleaning by removing .class files generated from your .java classes.
However, sometimes they may make mistakes. For example, when a JAR artifact coming from Maven Central and your own Java files have the same classes. The plugin won’t understand which of them to keep and most probably will delete both.
To make its behavior fully explicit, you may use one of these two options (or both):
<project>
[...]
<build>
[...]
<plugins>
[...]
<plugin>
<groupId>org.eolang</groupId>
<artifactId>eo-maven-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>register</goal>
<goal>assemble</goal>
<goal>transpile</goal>
<goal>copy</goal>
<goal>unplace</goal>
<goal>unspile</goal>
</goals>
<configuration>
<keepBinaries>
<glob>EOorg/EOeolang/EOfoo/**</glob>
</keepBinaries>
<removeBinaries>
<glob>EOorg/EOeolang/**.class</glob>
</removeBinaries>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
This configuration will ensure that only EOorg/EOeolang/EOfoo/** files
will stay in target/classes before the JAR is packaged. Also, if for
some magic reason EOorg/EOeolang/**.class will remain their, they will
also be deleted.
First, only what is mentioned in keepBinaries will stay.
Second, what is mentioned in removeBinaries will be deleted.
I think it’s a good practice to use keepBinaries option in your
library, just to be safe and sure that nothing aside from your compiled
atoms get into the JAR.