Значит смотри. Что такое несколько выполняемых файлов. Это просто несколько jar-файлов в которых просто есть нужный манифест. Я достигал это с помощью профилей и с помощью Makefile который уже автоматизировал сборку проекта. Вот пример проекта с двумя main артифактами. Приведу только ключевые фрагменты которые есть суть.
pom.xml
<profiles>
<profile>
<id>java</id>
<properties>
<main.class.name>org.example.JavaTemplate</main.class.name>
<jar.name>java-template</jar.name>
</properties>
</profile>
<profile>
<id>java-kafka-producer</id>
<properties>
<main.class.name>org.example.kafka.JavaKafkaProducerTemplate</main.class.name>
<jar.name>java-kafka-producer-template</jar.name>
</properties>
</profile>
....
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<Main-Class>${main.class.name}</Main-Class>
</manifest>
</archive>
<finalName>${jar.name}</finalName>
</configuration>
</plugin>
Makefile
java-kafka-producer-template: build
mvn package -DskipTests -Pjava-kafka-producer
cp -f target/java-kafka-producer-template.jar ./bin/
build: clean
mvn install dependency:copy-dependencies
cp -f target/dependency/* ./bin/
rsync src/main/resources/shell/* ./bin
clean:
rm -fr bin/*
mkdir -p bin/
...
Сразу скажу что я не искал коробочного решения в виде готового gradle/maven плагина. Я просто скриптовал последовательность действий для нескольких сборок. Фактически я делал несколько компилляций проекта с разными параметрами. Я думаю что я достиг своей цели не заморачиваясь java-перфекционизмом или зависимостью от IDE.