CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework-boot--spring-boot-loader-tools

Tools for generating executable JAR/WAR files with embedded containers for Spring Boot applications

Pending
Overview
Eval results
Files

layout-management.mddocs/

Archive Layout Management

Strategy-based system for determining how classes and libraries are organized within different archive types. The layout system supports JAR, WAR, and expanded directory structures with extensive customization options for different deployment scenarios.

Capabilities

Layout Interface

Core interface defining how archive contents are organized and accessed by the Spring Boot loader.

public interface Layout {
    /**
     * Get the launcher class name for this layout.
     * The launcher is responsible for bootstrapping the application.
     * 
     * @return the fully qualified launcher class name
     */
    String getLauncherClassName();
    
    /**
     * Get the location where a library should be placed within the archive.
     * 
     * @param libraryName the name of the library
     * @param scope the scope of the library (COMPILE, RUNTIME, etc.)
     * @return the path within the archive where the library should be placed
     */
    String getLibraryLocation(String libraryName, LibraryScope scope);
    
    /**
     * Get the location where application classes are stored.
     * 
     * @return the path within the archive where classes are located
     */
    String getClassesLocation();
    
    /**
     * Get the location of the classpath index file.
     * Default implementation returns "BOOT-INF/classpath.idx".
     * 
     * @return the path to the classpath index file
     */
    default String getClasspathIndexFileLocation() {
        return "BOOT-INF/classpath.idx";
    }
    
    /**
     * Get the location of the layers index file.
     * Default implementation returns "BOOT-INF/layers.idx".
     * 
     * @return the path to the layers index file
     */
    default String getLayersIndexFileLocation() {
        return "BOOT-INF/layers.idx";
    }
    
    /**
     * Determine if this layout produces executable archives.
     * 
     * @return true if the archive can be executed directly
     */
    boolean isExecutable();
}

Repackaging Layout

Specialized layout interface for repackaging existing archives with different class locations.

public interface RepackagingLayout extends Layout {
    /**
     * Get the location where repackaged classes should be stored.
     * This may differ from the original classes location.
     * 
     * @return the path for repackaged classes
     */
    String getRepackagedClassesLocation();
}

Custom Loader Layout

Interface for layouts that provide their own loader classes instead of using the standard Spring Boot loader.

public interface CustomLoaderLayout {
    /**
     * Write custom loader classes to the archive.
     * 
     * @param writer the writer for adding loader classes
     * @throws IOException if writing fails
     */
    void writeLoadedClasses(LoaderClassesWriter writer) throws IOException;
}

Standard Layouts

Pre-defined layout implementations for common archive types.

public final class Layouts {
    /**
     * Get the appropriate layout for the given file based on its extension and type.
     * 
     * @param file the file to determine layout for
     * @return the appropriate layout
     */
    public static Layout forFile(File file);
    
    /**
     * Standard JAR layout for executable JAR files.
     * Places libraries in BOOT-INF/lib/ and classes in BOOT-INF/classes/.
     */
    public static class Jar implements RepackagingLayout {
        @Override
        public String getLauncherClassName() {
            return "org.springframework.boot.loader.launch.JarLauncher";
        }
        
        @Override
        public String getLibraryLocation(String libraryName, LibraryScope scope) {
            return "BOOT-INF/lib/";
        }
        
        @Override
        public String getClassesLocation() {
            return "BOOT-INF/classes/";
        }
        
        @Override
        public String getRepackagedClassesLocation() {
            return "BOOT-INF/classes/";
        }
        
        @Override
        public boolean isExecutable() {
            return true;
        }
    }
    
    /**
     * Expanded JAR layout for directory-based deployment.
     * Similar to JAR layout but optimized for exploded directory structure.
     */
    public static class Expanded extends Jar {
        @Override
        public String getLauncherClassName() {
            return "org.springframework.boot.loader.launch.PropertiesLauncher";
        }
    }
    
    /**
     * No-operation layout that preserves original structure.
     * Used when no repackaging is desired.
     */
    public static class None extends Jar {
        @Override
        public boolean isExecutable() {
            return false;
        }
    }
    
    /**
     * WAR layout for web application archives.
     * Places libraries in WEB-INF/lib/ and classes in WEB-INF/classes/.
     */
    public static class War implements Layout {
        @Override
        public String getLauncherClassName() {
            return "org.springframework.boot.loader.launch.WarLauncher";
        }
        
        @Override
        public String getLibraryLocation(String libraryName, LibraryScope scope) {
            if (scope == LibraryScope.PROVIDED) {
                return "WEB-INF/lib-provided/";
            }
            return "WEB-INF/lib/";
        }
        
        @Override
        public String getClassesLocation() {
            return "WEB-INF/classes/";
        }
        
        @Override
        public boolean isExecutable() {
            return true;
        }
    }
}

Layout Factory

Factory interface for creating layout instances based on source files.

public interface LayoutFactory {
    /**
     * Create an appropriate layout for the given source file.
     * 
     * @param source the source file to create a layout for
     * @return the created layout
     */
    Layout getLayout(File source);
}

public class DefaultLayoutFactory implements LayoutFactory {
    /**
     * Create a layout based on file extension and characteristics.
     * - .jar files use Layouts.Jar
     * - .war files use Layouts.War
     * - Directories use Layouts.Expanded
     * 
     * @param source the source file
     * @return the appropriate layout
     */
    @Override
    public Layout getLayout(File source) {
        // Implementation determines layout based on file type
    }
}

Usage Examples

Basic Layout Selection

import org.springframework.boot.loader.tools.Layout;
import org.springframework.boot.loader.tools.Layouts;
import java.io.File;

// Automatic layout selection
File jarFile = new File("myapp.jar");
Layout layout = Layouts.forFile(jarFile);
System.out.println("Launcher: " + layout.getLauncherClassName());
System.out.println("Classes location: " + layout.getClassesLocation());
System.out.println("Executable: " + layout.isExecutable());

// Output for JAR file:
// Launcher: org.springframework.boot.loader.launch.JarLauncher
// Classes location: BOOT-INF/classes/
// Executable: true

Explicit Layout Configuration

import org.springframework.boot.loader.tools.*;
import java.io.File;

// Use specific layout with repackager
File sourceJar = new File("myapp.jar");
Repackager repackager = new Repackager(sourceJar);

// Force WAR layout even for JAR file
Layout warLayout = new Layouts.War();
repackager.setLayout(warLayout);

// Libraries will be placed in WEB-INF/lib/ instead of BOOT-INF/lib/
repackager.repackage(Libraries.NONE);

Custom Layout Implementation

import org.springframework.boot.loader.tools.*;

// Create custom layout for special deployment requirements
public class CustomLayout implements RepackagingLayout {
    @Override
    public String getLauncherClassName() {
        return "com.example.CustomLauncher";
    }
    
    @Override
    public String getLibraryLocation(String libraryName, LibraryScope scope) {
        // Separate compile and runtime dependencies
        if (scope == LibraryScope.COMPILE) {
            return "CUSTOM-INF/compile-lib/";
        }
        return "CUSTOM-INF/runtime-lib/";
    }
    
    @Override
    public String getClassesLocation() {
        return "CUSTOM-INF/app-classes/";
    }
    
    @Override
    public String getRepackagedClassesLocation() {
        return "CUSTOM-INF/app-classes/";
    }
    
    @Override
    public boolean isExecutable() {
        return true;
    }
}

// Use custom layout
File sourceJar = new File("myapp.jar");
Repackager repackager = new Repackager(sourceJar);
repackager.setLayout(new CustomLayout());
repackager.repackage(Libraries.NONE);

Layout Factory Usage

import org.springframework.boot.loader.tools.*;
import java.io.File;

// Custom layout factory for special file types
public class CustomLayoutFactory implements LayoutFactory {
    @Override
    public Layout getLayout(File source) {
        if (source.getName().endsWith(".ubar")) {
            return new Layouts.War(); // Treat .ubar files as WAR
        }
        if (source.getName().contains("micro")) {
            return new Layouts.Expanded(); // Use expanded layout for micro services
        }
        return Layouts.forFile(source); // Default behavior
    }
}

// Configure repackager with custom factory
File sourceFile = new File("myapp.ubar");
Repackager repackager = new Repackager(sourceFile);
repackager.setLayoutFactory(new CustomLayoutFactory());
repackager.repackage(Libraries.NONE);

Understanding Library Placement

import org.springframework.boot.loader.tools.*;
import java.io.File;

// Examine how different layouts handle library placement
Layout jarLayout = new Layouts.Jar();
Layout warLayout = new Layouts.War();

String libName = "spring-core-5.3.21.jar";

// JAR layout
String jarLibLocation = jarLayout.getLibraryLocation(libName, LibraryScope.COMPILE);
System.out.println("JAR layout lib location: " + jarLibLocation);
// Output: BOOT-INF/lib/

// WAR layout with different scopes
String warCompileLocation = warLayout.getLibraryLocation(libName, LibraryScope.COMPILE);
String warProvidedLocation = warLayout.getLibraryLocation(libName, LibraryScope.PROVIDED);
System.out.println("WAR compile location: " + warCompileLocation);
System.out.println("WAR provided location: " + warProvidedLocation);
// Output: WEB-INF/lib/
// Output: WEB-INF/lib-provided/

Custom Loader Layout

import org.springframework.boot.loader.tools.*;
import java.io.IOException;

// Layout with custom loader classes
public class CustomLoaderLayout implements Layout, CustomLoaderLayout {
    @Override
    public String getLauncherClassName() {
        return "com.example.CustomBootstrap";
    }
    
    @Override
    public String getLibraryLocation(String libraryName, LibraryScope scope) {
        return "META-INF/libs/";
    }
    
    @Override
    public String getClassesLocation() {
        return "META-INF/classes/";
    }
    
    @Override
    public boolean isExecutable() {
        return true;
    }
    
    @Override
    public void writeLoadedClasses(LoaderClassesWriter writer) throws IOException {
        // Write custom loader classes
        try (var stream = getClass().getResourceAsStream("/custom-loader.jar")) {
            writer.writeLoaderClasses("custom-loader.jar");
        }
    }
}

Layout Decision Matrix

File TypeDefault LayoutLauncher ClassClasses LocationLibraries Location
.jarLayouts.JarJarLauncherBOOT-INF/classes/BOOT-INF/lib/
.warLayouts.WarWarLauncherWEB-INF/classes/WEB-INF/lib/
DirectoryLayouts.ExpandedPropertiesLauncherBOOT-INF/classes/BOOT-INF/lib/
OtherLayouts.JarJarLauncherBOOT-INF/classes/BOOT-INF/lib/

The layout system provides the foundation for Spring Boot's flexible packaging model, enabling different deployment strategies while maintaining consistent runtime behavior.

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework-boot--spring-boot-loader-tools

docs

build-integration.md

image-packaging.md

index.md

jar-writing.md

launch-scripts.md

layer-support.md

layout-management.md

library-management.md

main-class-detection.md

repackaging.md

tile.json