Tools for generating executable JAR/WAR files with embedded containers for Spring Boot applications
—
Core functionality for transforming regular JAR/WAR files into executable Spring Boot archives. The repackaging process handles main class detection, library inclusion, manifest generation, and loader class integration to create self-contained executable files.
Transform a regular JAR into an executable Spring Boot JAR with embedded dependencies and loader classes.
public class Repackager {
/**
* Create a repackager for the given source file.
*
* @param source the source JAR or WAR file to repackage
*/
public Repackager(File source);
/**
* Repackage the source file with the given libraries.
* Creates a backup of the original file and replaces it with the repackaged version.
*
* @param libraries the libraries to include in the repackaged file
* @throws IOException if the repackaging fails
*/
public void repackage(Libraries libraries) throws IOException;
/**
* Repackage the source file to a specific destination with the given libraries.
*
* @param destination the destination file for the repackaged archive
* @param libraries the libraries to include in the repackaged file
* @throws IOException if the repackaging fails
*/
public void repackage(File destination, Libraries libraries) throws IOException;
/**
* Repackage with launch script support for Unix-like systems.
*
* @param destination the destination file
* @param libraries the libraries to include
* @param launchScript the launch script to prepend to the JAR
* @throws IOException if the repackaging fails
*/
public void repackage(File destination, Libraries libraries, LaunchScript launchScript) throws IOException;
/**
* Full control repackaging with launch script and custom modification time.
*
* @param destination the destination file
* @param libraries the libraries to include
* @param launchScript the launch script to prepend
* @param lastModifiedTime the last modified time to set on entries
* @throws IOException if the repackaging fails
*/
public void repackage(File destination, Libraries libraries, LaunchScript launchScript, FileTime lastModifiedTime) throws IOException;
/**
* Configure whether to create a backup of the source file.
*
* @param backupSource true to create a backup, false otherwise
*/
public void setBackupSource(boolean backupSource);
}Abstract base class providing extensive customization options for the packaging process.
public abstract class Packager {
/**
* Create a packager for the given source file.
*
* @param source the source file to package
*/
protected Packager(File source);
/**
* Set the main class for the executable archive.
* If not set, the main class will be automatically detected.
*
* @param mainClass the fully qualified main class name
*/
public void setMainClass(String mainClass);
/**
* Set the layout strategy for organizing archive contents.
*
* @param layout the layout to use
*/
public void setLayout(Layout layout);
/**
* Set the loader implementation to use.
*
* @param loaderImplementation the loader implementation
*/
public void setLoaderImplementation(LoaderImplementation loaderImplementation);
/**
* Set the factory for creating layouts.
*
* @param layoutFactory the layout factory
*/
public void setLayoutFactory(LayoutFactory layoutFactory);
/**
* Set the layers configuration for Docker optimization.
*
* @param layers the layers configuration
*/
public void setLayers(Layers layers);
/**
* Configure whether to include relevant JAR mode libraries.
*
* @param includeRelevantJarModeJars true to include JAR mode libraries
*/
public void setIncludeRelevantJarModeJars(boolean includeRelevantJarModeJars);
/**
* Get the backup file location.
*
* @return the backup file location
*/
public File getBackupFile();
/**
* Add a listener for main class timeout warnings.
*
* @param listener the warning listener
*/
public void addMainClassTimeoutWarningListener(MainClassTimeoutWarningListener listener);
}Specialized packager for creating container images with custom export handling.
public class ImagePackager extends Packager {
/**
* Create an image packager for the given source file.
*
* @param source the source file to package
*/
public ImagePackager(File source);
/**
* Package for image creation with custom entry export handling.
*
* @param libraries the libraries to include
* @param exporter custom handler for processing ZIP entries
* @throws IOException if packaging fails
*/
public void packageImage(Libraries libraries, BiConsumer<ZipEntry, EntryWriter> exporter) throws IOException;
}@FunctionalInterface
public interface MainClassTimeoutWarningListener {
/**
* Called when main class detection times out.
*
* @param duration the time taken for the search
* @param mainClass the main class that was found (may be null)
*/
void handleTimeoutWarning(Duration duration, String mainClass);
}import org.springframework.boot.loader.tools.Repackager;
import org.springframework.boot.loader.tools.Libraries;
import java.io.File;
File sourceJar = new File("myapp.jar");
Repackager repackager = new Repackager(sourceJar);
// Repackage with no additional libraries
repackager.repackage(Libraries.NONE);
// The original JAR is backed up and replaced with the executable version
// Run with: java -jar myapp.jarimport org.springframework.boot.loader.tools.*;
import java.io.File;
import java.util.List;
File sourceJar = new File("myapp.jar");
File destination = new File("myapp-executable.jar");
Repackager repackager = new Repackager(sourceJar);
// Create libraries collection
List<File> libraryFiles = List.of(
new File("lib/spring-boot.jar"),
new File("lib/spring-context.jar"),
new File("lib/logback-classic.jar")
);
Libraries libraries = callback -> {
for (File libFile : libraryFiles) {
LibraryScope scope = libFile.getName().contains("test")
? LibraryScope.PROVIDED
: LibraryScope.COMPILE;
callback.library(new Library(libFile, scope));
}
};
// Repackage to specific destination
repackager.repackage(destination, libraries);import org.springframework.boot.loader.tools.*;
import java.io.File;
import java.util.Map;
File sourceJar = new File("myapp.jar");
Repackager repackager = new Repackager(sourceJar);
// Configure advanced options
repackager.setMainClass("com.example.MyApplication");
repackager.setLayout(Layouts.JAR);
repackager.setLoaderImplementation(LoaderImplementation.DEFAULT);
repackager.setBackupSource(true);
// Add timeout warning listener
repackager.addMainClassTimeoutWarningListener((duration, mainClass) -> {
System.out.println("Main class detection took " + duration.toMillis() + "ms");
if (mainClass == null) {
System.out.println("No main class found!");
}
});
// Create launch script for Unix systems
File scriptTemplate = new File("launch-script.sh");
Map<String, String> properties = Map.of(
"initInfoProvides", "myapp",
"initInfoShortDescription", "My Spring Boot Application"
);
LaunchScript launchScript = new DefaultLaunchScript(scriptTemplate, properties);
// Repackage with launch script
File destination = new File("myapp-executable.jar");
repackager.repackage(destination, Libraries.NONE, launchScript);
// The resulting JAR can be executed directly: ./myapp-executable.jarInstall with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-loader-tools