Skip to content

Runtime-Based MicroProfile Config Validation for LSP4MP #511

@angelozerr

Description

@angelozerr

MicroProfile Config IDE Support — Runtime-Accurate Validation

Today, LSP4MP performs configuration validation using a hardcoded set of converters.
This means that validation does not always match how the application behaves at runtime:

  • Custom project converters are ignored
  • Many built-in conversions are missing or simplified
    (e.g., Duration, URL, collection types, vendor extensions)
  • Error messages reported in the editor often differ from the real runtime behavior

This can lead to situations where configuration appears valid in the IDE but fails once the
application is started — or the opposite.

This project introduces a new runtime-based validation mechanism.

It should fix:

What This Changes

Instead of re-implementing conversion logic, the MicroProfile Language Server now:

  1. Retrieves the classpath JARs of the user's project (via Gradle/Maven/build tool / IDE)
  2. Loads them in a dedicated, isolated classloader
  3. Uses ConfigProviderResolver to initialize the real MicroProfile Config runtime
  4. Discovers and instantiates all Converter<?> implementations found in dependencies
  5. Validates configuration values using the same logic the application will use at runtime

Result

The validation performed in the IDE is now identical to the validation performed by the running application.

No duplicated logic. No mismatches. No surprises at deployment.

Runtime-Based MicroProfile Config Validation for LSP4MP

Today, LSP4MP performs configuration validation using a hardcoded set of converters.
This means that validation does not always match how the application behaves at runtime:

  • Custom project converters are not taken into account
  • Many built-in conversions are simplified or missing (e.g., Duration, URL, List, Set, etc.)
  • Error messages differ from what the actual MicroProfile Config implementation would produce

As a result, configuration that appears valid in the editor may fail at runtime, and the
opposite can also happen.

This project introduces a new validation mechanism that uses the real MicroProfile Config
runtime
, discovered from the project's classpath.


What This Changes

The language server now:

  1. Retrieves the list of project dependency JARs from the IDE (Gradle, Maven, etc.)
  2. Loads them in an isolated classloader
  3. Uses ConfigProviderResolver to bootstrap the actual MicroProfile Config implementation
  4. Discovers and instantiates all Converter<?> implementations found on the classpath
  5. Validates configuration values using the same conversion logic used by the running application

The IDE now performs the exact same validation that the application performs at runtime.


Examples

1. Validation in application.properties

If the project uses a converter for Duration (such as SmallRye's built-in one):

my.timeout=42    # ❌ Invalid: not a valid Duration
my.timeout=25s   # ✅ Valid: converted to a 25-second Duration

1. Validation of @ConfigProperty(defaultValue)

@ConfigProperty(name = "service.retry", defaultValue = "abc")
int retryCount;

Key Features

  • Runtime-accurate type conversion

    • Uses the actual MicroProfile Config implementation present in the project
  • Custom converters supported

    • Any converter found on the classpath is automatically discovered and used
  • Correct validation for complex types

    • Duration, LocalDate, enums, collections, vendor-specific converters, etc.
  • Accurate error messages

    • Same exception messages as the real application runtime
  • Framework-independent
    Works with:

    • SmallRye Config (Quarkus, WildFly, standalone)
    • Helidon MP
    • Open Liberty
    • Payara
    • Apache Geronimo Config
    • Any other compliant MicroProfile implementation

Current Limitations

  • For now, only converters located in project JAR dependencies are supported
    (source-defined converters will be supported later)
  • The Java version running the Language Server must be able to execute the loaded converters
    (ex: LS running on Java 17 cannot execute converters compiled for Java 21)

Why This Matters

With this enhancement:

✅ If the application would accept a configuration value → the IDE marks it valid
❌ If the application would fail to convert it → the IDE reports the same failure

This ensures consistency between development and runtime, reducing debugging overhead
and improving developer confidence.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions