Skip to content

Conversation

@machacjozef
Copy link
Member

@machacjozef machacjozef commented May 22, 2025

Description

Introduced functionality to generate custom JAR manifests with project metadata and optional output configurations. Added logic to scan and generate Spring AutoConfiguration.imports files for auto-configuration support. Updated dependencies and version bump to 1.1.0 to reflect new features.

Dependencies

Third party dependencies

  • ClassGraph [https://github.com/classgraph/classgraph]

Blocking Pull requests

There are no dependencies on other PR

How Has Been This Tested?

manually

Test Configuration

<Please describe configuration for tests to run if applicable, like program parameters, host OS, VM configuration etc.>

Name Tested on
OS
Runtime
Dependency Manager
Framework version
Run parameters
Other configuration

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes have been checked, personally or remotely, with @tuplle
  • I have commented my code, particularly in hard-to-understand areas
  • I have resolved all conflicts with the target branch of the PR
  • I have updated and synced my code with the target branch
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes:
    • Lint test
    • Unit tests
    • Integration tests
  • I have checked my contribution with code analysis tools:
  • I have made corresponding changes to the documentation:
    • Developer documentation
    • User Guides
    • Migration Guides

Summary by CodeRabbit

  • New Features

    • Added the ability to generate JAR files with a custom manifest containing detailed project metadata.
    • Automatically generates Spring Boot auto-configuration imports based on detected configuration classes.
  • Chores

    • Updated project version to 1.1.0.
    • Added a new dependency to improve classpath scanning capabilities.
  • Refactor

    • Improved code structure for artifact handling and logging.
    • Replaced Lombok constructors and getters with explicit implementations for better clarity.

Introduced functionality to generate custom JAR manifests with project metadata and optional output configurations. Added logic to scan and generate Spring `AutoConfiguration.imports` files for auto-configuration support. Updated dependencies and version bump to 1.1.0 to reflect new features.
@machacjozef machacjozef self-assigned this May 22, 2025
@machacjozef machacjozef added the enhancement New feature or request label May 22, 2025
@coderabbitai
Copy link

coderabbitai bot commented May 22, 2025

Walkthrough

The project version in the Maven configuration was updated and a new dependency on the classgraph library was added. The BuildModuleMojo class received enhancements to generate JARs with custom manifests and to create Spring Boot auto-configuration import files. Additionally, SimpleArtifact constructors and getters were made explicit.

Changes

File(s) Change Summary
pom.xml Updated project version from 1.0.1 to 1.1.0 and added a compile-time dependency on classgraph version 4.8.179.
src/main/java/com/netgrif/maven/plugin/module/BuildModuleMojo.java Added methods to create JARs with custom manifests and to generate Spring Boot auto-configuration import files using ClassGraph. Introduced a new boolean parameter to control JAR output behavior. Changed logging calls to use a log() method. Integrated new steps into the execution flow, with proper exception handling.
src/main/java/com/netgrif/maven/plugin/module/parameters/SimpleArtifact.java Removed Lombok constructor annotations and added explicit no-argument and three-argument constructors. Added explicit getter methods for all fields, in addition to existing Lombok-generated methods.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Maven
    participant BuildModuleMojo
    participant ClassGraph
    participant FileSystem

    User->>Maven: Run build
    Maven->>BuildModuleMojo: Execute Mojo
    BuildModuleMojo->>BuildModuleMojo: Collect dependencies
    BuildModuleMojo->>BuildModuleMojo: generateSpringFactoriesToOutputDir()
    BuildModuleMojo->>ClassGraph: Scan for @Configuration/@AutoConfiguration classes
    ClassGraph-->>BuildModuleMojo: Return list of configuration classes
    BuildModuleMojo->>FileSystem: Write AutoConfiguration.imports file
    BuildModuleMojo->>BuildModuleMojo: createJarWithCustomManifest()
    BuildModuleMojo->>FileSystem: Read original JAR
    BuildModuleMojo->>BuildModuleMojo: buildCustomManifest()
    BuildModuleMojo->>FileSystem: Write new JAR with custom manifest
    BuildModuleMojo->>Maven: Continue packaging
Loading

Poem

A hop and a skip, a version anew,
With ClassGraph in tow, more magic to do!
Custom manifests crafted, Spring configs in place,
Constructors explicit—no Lombok to chase.
The build leaps ahead, like a rabbit in spring,
Each change a soft thump, a delightful new thing!
🐇✨

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 30th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c38b2f8 and 9bc02f9.

📒 Files selected for processing (1)
  • pom.xml (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • pom.xml
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/main/java/com/netgrif/maven/plugin/module/parameters/SimpleArtifact.java (1)

47-57: Consider removing explicit getters or Lombok's @DaTa

Since the class is already annotated with Lombok's @DaTa which automatically generates getters, these explicit getters create redundancy. Either:

  1. Remove the explicit getters and rely on Lombok, or
  2. Replace @DaTa with more specific annotations like @Getter or remove Lombok dependency altogether
- @Data
+ @Getter
  public class SimpleArtifact {
      // Keep the rest of the class as is
  }

Or alternatively:

  @Data
  public class SimpleArtifact {
      // Keep all constructors and other methods

-     public String getGroupId() {
-         return groupId;
-     }
- 
-     public String getArtifactId() {
-         return artifactId;
-     }
- 
-     public String getVersion() {
-         return version;
-     }
  }
src/main/java/com/netgrif/maven/plugin/module/BuildModuleMojo.java (4)

209-282: Comprehensive manifest generation

The manifest generation captures extensive project metadata which enhances the JAR's information content. Consider adding a comment documenting the purpose and format of these custom attributes.

  private Manifest buildCustomManifest() throws IOException {
+     // Build a custom JAR manifest that includes comprehensive project metadata
+     // All custom attributes are prefixed with "Netgrif-" to avoid conflicts
      File sourceJar = new File(project.getBuild().getDirectory(), project.getBuild().getFinalName() + ".jar");
      // Rest of the method...

284-288: Useful utility method

The putIfNotNull helper method is a clean approach to conditionally adding entries to the manifest. Consider making it static since it doesn't use instance variables.

- private void putIfNotNull(Map<String, String> map, String key, Object value) {
+ private static void putIfNotNull(Map<String, String> map, String key, Object value) {
      if (value != null && !String.valueOf(value).isBlank()) {
          map.put(key, String.valueOf(value));
      }
  }

386-419: Effective Spring auto-configuration support

The implementation for scanning and generating Spring auto-configuration imports follows Spring Boot conventions. A few suggestions for improvement:

  1. Consider adding defensive validation for the output directory existence
  2. Add detailed logging at debug level for scanning operations
  3. Consider making the generated file path configurable via a Maven parameter
  private void generateSpringFactoriesToOutputDir() throws IOException {
      String outputDir = project.getBuild().getOutputDirectory();
+     if (outputDir == null || outputDir.isBlank()) {
+         log().warn("Output directory is not available. Skipping Spring factories generation.");
+         return;
+     }
      File springMetaInf = new File(outputDir, "META-INF/spring");
      if (!springMetaInf.exists()) {
-         springMetaInf.mkdirs();
+         if (!springMetaInf.mkdirs()) {
+             log().warn("Failed to create directory: " + springMetaInf.getAbsolutePath());
+             return;
+         }
      }
+     log().debug("Scanning for Spring configuration classes in: " + outputDir);
      List<String> configClasses = new ArrayList<>();
      try (ScanResult scanResult = new ClassGraph()
              .overrideClasspath(outputDir)
              .enableAnnotationInfo()
              .enableClassInfo()
              .scan()) {

397-404: Consider adding support for additional Spring annotations

The current implementation scans for @configuration and @autoConfiguration. You might want to include additional Spring annotations like @component or @service to make the feature more comprehensive.

  for (ClassInfo ci : scanResult.getAllClasses()) {
      if (ci.hasAnnotation("org.springframework.context.annotation.Configuration")
-             || ci.hasAnnotation("org.springframework.boot.autoconfigure.AutoConfiguration")) {
+             || ci.hasAnnotation("org.springframework.boot.autoconfigure.AutoConfiguration")
+             || ci.hasAnnotation("org.springframework.stereotype.Component")
+             || ci.hasAnnotation("org.springframework.stereotype.Service")) {
          configClasses.add(ci.getName());
      }
  }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81901ef and c38b2f8.

📒 Files selected for processing (3)
  • pom.xml (2 hunks)
  • src/main/java/com/netgrif/maven/plugin/module/BuildModuleMojo.java (9 hunks)
  • src/main/java/com/netgrif/maven/plugin/module/parameters/SimpleArtifact.java (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
🔇 Additional comments (8)
pom.xml (1)

9-9: Version bump is appropriate for new features

The version increment from 1.0.1 to 1.1.0 follows semantic versioning principles, where a minor version increase indicates backward-compatible functionality additions.

src/main/java/com/netgrif/maven/plugin/module/parameters/SimpleArtifact.java (1)

27-34: Explicit constructors improve code clarity

Adding explicit constructors makes the instantiation patterns clearer and provides better control over object creation. This is good practice even with Lombok's @DaTa annotation present.

src/main/java/com/netgrif/maven/plugin/module/BuildModuleMojo.java (6)

51-53: Good logging abstraction

Creating a log() wrapper method improves code readability and makes log statements more concise throughout the class.


79-80: Well-defined configuration parameter

The customManifestOutputJar parameter with a default value provides good control over whether to modify the original JAR or create a separate output JAR.


109-117: Proper exception handling

Good practice to catch IOException separately and rethrow as MojoExecutionException with a descriptive message. This follows Maven plugin best practices.


161-185: Well-implemented JAR creation logic

The implementation handles both in-place JAR modification and separate output JAR creation based on the configuration parameter. The early return if the source JAR doesn't exist is a good defensive approach.


187-207: Efficient JAR processing

The JAR copying implementation uses proper resource management with try-with-resources and an efficient buffered copying approach. The manifest entry is correctly excluded from being copied.


256-278: Elegant developer information formatting

The code that formats developer information is well-structured and handles optional information (email, organization) elegantly. The filter for null values and joining with line breaks creates a clean format.

Upgraded the ClassGraph library from 4.8.147 to 4.8.179 in `pom.xml`. This update includes the latest fixes and enhancements for improved performance and compatibility.
@machacjozef machacjozef merged commit ffd6380 into main May 22, 2025
4 of 5 checks passed
@machacjozef machacjozef deleted the feature/manifest-info branch May 22, 2025 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants