To build the project, simply run:
mvn clean packageThis will generate the executable JAR file in the target/ directory.
# Show all available commands
java -jar dev-toolkit-1.0.0.jar --help
# Get help for a specific command
java -jar dev-toolkit-1.0.0.jar split --helpThe MethodIntrospector tool allows you to extract metadata about all methods in a given Java class file. It outputs a JSON file containing each method's name, return type, and number of lines (including static, private, public, etc.).
java -jar dev-toolkit-1.0.0.jar introspect <path-to-java-file>Example:
java -jar dev-toolkit-1.0.0.jar introspect src/data/PublishCommonService.javaThis will produce a file named PublishCommonService_methods.json in the current directory.
{
"moveLessFolderFromSrcToDest": {
"return_type": "boolean",
"num_lines": 61
},
...
}
- Each key is a method name.
return_typeis the method's return type as a string.num_linesis the number of lines in the method (including signature and body).
Walks a Play Framework repo’s app/ tree and writes transformed Java files into a Spring-style project under <target>/src/main/java, preserving package paths relative to app/. Layer (controller, service, repository, etc.) is inferred from path segments (see LayerDetector).
java -jar dev-toolkit-1.0.0.jar migrate-app [OPTIONS]# From the Play repo root (expects ./app)
java -jar dev-toolkit-1.0.0.jar migrate-app
# Explicit Play and Spring roots
java -jar dev-toolkit-1.0.0.jar migrate-app --source /path/to/play-project --target /path/to/spring-project
# Preview only
java -jar dev-toolkit-1.0.0.jar migrate-app --source . --dry-run
# Only controllers, first 10 new files, with a report
java -jar dev-toolkit-1.0.0.jar migrate-app --layer controller --batch-size 10 --report ./migrate-report.jsonFor one file instead of the whole tree:
java -jar dev-toolkit-1.0.0.jar transform --input app/com/example/Foo.java --output /path/to/spring/src/main/java/com/example/Foo.java [--layer controller|service|...] [--report report.json]Layer defaults to auto-detection from the input path when --layer is omitted.
migrate-app / transform do not create a Spring Boot project from scratch. You still need a target repo with a build (pom.xml / Gradle) and dependencies.
The toolkit applies AST-level updates on each file, including:
- Spring stereotypes by folder layer (
@RestController,@Service,@Component,@Repository) javax.inject.Inject→@Autowired(fields, constructors, method parameters)- Play
Logger.ALogger/Log.getLogger(Class)→ SLF4JLoggerFactory.getLogger(Class) - All layers:
play.libs.Json→ Jackson on an@Autowired ObjectMapper objectMapperfield when needed:Json.newObject/newArray→createObjectNode/createArrayNode,fromJson/toJson/parse→convertValue/valueToTree/readTree; unusedimport play.libs.Jsonis dropped. - All layers:
play.libs.ws.WSClient/WSResponse→RestTemplate/ResponseEntity<String>; commonws.url(...).setHeader/post/get...toCompletableFuture()[.get()]andthenApply(WSResponse::asJson)patterns →RestTemplate+HttpHeaders/HttpEntity+objectMapper.readTreewhere needed;play.inject.ApplicationLifecycle#addStopHook→@PreDestroymethod and constructor cleanup. Remaining Play-WS edge cases may need manual fixes. - Controllers only: drop
extends Controller, remove@BodyParser, replaceHttpExecution.fromThread(executor)withexecutor; rewriteHttp.Request(JSON body + optionaljavax.servlet.http.HttpServletRequest),Result/CompletableFuture<Result>→ResponseEntity<JsonNode>, and common Play response helpers (ok,created,badRequest, …) toResponseEntity; strip other obsoleteplay.*imports. Spring Boot 3 may needjakarta.servletinstead ofjavax.servlet.
You must still add request mappings (@GetMapping, @PostMapping, …), migrate any remaining Play request APIs (e.g. headers) to servlet/Spring types, and align service method signatures with callers. For Play conf/routes, a companion script in consuming repos can emit mapping hints, e.g. python3 scripts/routes_to_spring_map.py conf/routes in cms-content-service.
The toolkit includes a TestPromptGenerator that creates structured prompts for generating JUnit tests with LLMs. This tool extracts methods from Java classes and generates comprehensive prompts that can be used with ChatGPT, Gemini, or other LLMs.
java -jar dev-toolkit-1.0.0.jar generate-prompts --package <directory> [--class <className>] [--output <fileName>]Parameters:
--package: Path to the package (directory) to search (required)--class: Name of the Java class (without .java) - optional--output: Output file name - optional
Examples:
# Generate prompts for specific class
java -jar dev-toolkit-1.0.0.jar generate-prompts --package src/main/java --class MyClassI have a JSON object containing method names and their metadata. I need you to categorize these methods into logical service classes following these strict guidelines:
**CRITICAL VALIDATION REQUIREMENTS:**
- Every method from the input JSON must appear in exactly one service class array
- No method should be duplicated across multiple classes
- No method should be omitted from the output
- After categorization, verify that the total count of methods in all classes equals the original input count
**CATEGORIZATION GUIDELINES:**
1. **Functional Cohesion**: Group methods that perform related business functions together
2. **Data Cohesion**: Group methods that operate on the same data structures or models
3. **Reasonable Class Size**: Each class should have a maximum of 2000 lines of code (estimate based on method line counts)
4. **Clear Responsibilities**: Each class should have a single, well-defined purpose
5. **Naming Convention**: Use descriptive service class names ending with "Service", "Manager", or similar
6. **Logical Organization**:
- Group related CRUD operations together
- Separate utility/helper methods from business logic
- Keep configuration and settings methods together
- Separate query/retrieval methods from modification methods
**COMMON SERVICE PATTERNS TO CONSIDER:**
- LifecycleService (create, update, delete operations)
- QueryService (read/retrieval operations)
- ValidationService (validation and utility functions)
- RenderingService (UI/display related functions)
- ConfigurationService (settings and configuration)
- IntegrationService (external service integrations)
- MetadataService (metadata management)
- FileService (file operations)
**OUTPUT FORMAT:**
Provide the result as a JSON object where:
- Keys are service class names
- Values are arrays of method names belonging to that class
**VALIDATION SECTION:**
After the categorization, include:
1. Total method count validation
2. Brief description of each service class's responsibility
3. Estimated line count per service (sum of method line counts)
**INPUT JSON:**
[PASTE THE OUTPUT OF introspect command JSON HERE]
- Generate Split Classes
- Once you have the finalized
split_classes.json, run the toolkit to generate the split classes:
- Once you have the finalized
java -jar dev-toolkit-1.0.0.jar split <input-file> <output-directory> <mapping-json>Example:
java -jar dev-toolkit-1.0.0.jar split src/main/java/com/example/BigClass.java output/ split_classes.json
# Use constructor injection instead of field injection (default)
java -jar dev-toolkit-1.0.0.jar split src/main/java/com/example/BigClass.java output/ split_classes.json --injection-style=constructor
# Use Play framework annotation style with field injection
java -jar dev-toolkit-1.0.0.jar split src/main/java/com/example/BigClass.java output/ split_classes.json --annotation-style=play --injection-style=fieldOptions:
--annotation-style: Specify annotation style (javaorplay, default: auto-detect)--injection-style: Specify dependency injection style (fieldorconstructor, default:field)
Note:
- The
splitcommand now also performs verification internally after splitting, ensuring that all methods listed in your mapping exist in the generated split classes. You can still use theverifycommand separately if you want to re-check later or after manual changes.
- Undo Changes: Revert to your original class file and start over
- Modify Classification: Update the method groupings in your
split_classes.jsonfile and re-run the split command - Watch for Cyclic Dependencies: If the tool detects cyclic dependencies, it will analyze the cycles and propose method redistributions to resolve them. You will be prompted to confirm these changes before they are applied automatically.
- Review and Modify Proposed Changes: When cyclic dependencies are detected, the tool will save proposed changes to
split_classes_proposed.jsonand show you exactly what methods will be moved. You can:- Review the proposed changes and accept them as-is by entering 'y'
- Modify the
split_classes_proposed.jsonfile to customize the changes, then enter 'y' to use your modifications - Enter 'n' to cancel and manually modify your original
split_classes.jsoninstead
- Test Compilation and Runtime: Compile the generated classes to check for compilation issues and run your service to ensure there are no cyclic dependencies or runtime errors
The toolkit supports two dependency injection patterns:
- Uses
@Injectannotations directly on fields - Fields are not marked as
final - No constructor parameters needed
- Example:
public class OriginalClass {
@Inject
private ServiceA serviceA;
@Inject
private ServiceB serviceB;
public void delegateMethod() {
return serviceA.someMethod();
}
}- Uses
@Injecton constructor with all dependencies as parameters - Fields are marked as
final - All dependencies passed through constructor
- Example:
public class OriginalClass {
private final ServiceA serviceA;
private final ServiceB serviceB;
@Inject
public OriginalClass(ServiceA serviceA, ServiceB serviceB) {
this.serviceA = serviceA;
this.serviceB = serviceB;
}
public void delegateMethod() {
return serviceA.someMethod();
}
}Usage:
- Default:
--injection-style=field(can be omitted) - Constructor injection:
--injection-style=constructor
split: Split a large Java class into smaller service classes with delegation , it also verifies that none of the methods are lost during the operationverify: Verify that all methods in mapping exist in generated split classesintrospect: Extract metadata about all methods in a Java classtransform: Transform a single Play Java file to a Spring-friendly version (by layer)migrate-app: Migrate an entire Playapp/tree to a Spring repo’ssrc/main/javagenerate-prompts: Generate structured prompts for JUnit test creation with LLMsundoChanges: Restore original class and remove generated split artifacts using.split_undo.json
-h, --help: Show help message-V, --version: Display version information
- Java 8+
- The mapping file should be a JSON file mapping class names to lists of method names.
{
"SiteFeaturePublishService": ["publishMoveToProdFromPreprod", "publishAudience"],
"SiteConfigAndAssetService": ["moveLessFolderFromSrcToDest", "addLanguageInDefaultConfig"]
}- After building, only one JAR (
dev-toolkit-1.0.0.jar) will be generated in thetarget/directory (the version will match your Maven project version). - Generated classes are written to the specified output directory.
- The original class is refactored to delegate to the new service classes.
Use the verify command to check that all methods in your mapping exist in the generated classes:
java -jar dev-toolkit-1.0.0.jar verify <output-directory> <mapping-json>Example:
java -jar dev-toolkit-1.0.0.jar verify output/ split_classes.jsonNote:
- The verification script checks for the presence of all methods listed in your mapping, regardless of their visibility (public, protected, private, or package-private). This ensures that methods are not falsely reported as missing if they are present but not public.
The verify command prints a summary of any missing methods for each class.
For more details, see the code and comments in JavaClassSplitter.java.
