Skip to content

Commit

Permalink
Maven plugin for Helidon Service Inject
Browse files Browse the repository at this point in the history
  • Loading branch information
tomas-langer committed Nov 27, 2024
1 parent 43301ef commit c192431
Show file tree
Hide file tree
Showing 25 changed files with 3,140 additions and 0 deletions.
4 changes: 4 additions & 0 deletions all/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,10 @@
<groupId>io.helidon.service.inject</groupId>
<artifactId>helidon-service-inject</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.service.inject</groupId>
<artifactId>helidon-service-inject-maven-plugin</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.metadata</groupId>
<artifactId>helidon-metadata-hson</artifactId>
Expand Down
5 changes: 5 additions & 0 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,11 @@
<artifactId>helidon-service-inject</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.service.inject</groupId>
<artifactId>helidon-service-inject-maven-plugin</artifactId>
<version>${helidon.version}</version>
</dependency>

<!-- Metadata -->
<dependency>
Expand Down
24 changes: 24 additions & 0 deletions service/inject/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Helidon Inject includes:
- [Aspect Oriented Programming (interceptors)](#interceptors)
- [Events](events)
- [Programmatic Lookup](#programmatic-lookup)
- [Startup](#startup)
- [Other](#other)
- [Glossary](#glossary)

Expand Down Expand Up @@ -361,6 +362,29 @@ Lookup parameter options:
- `TypeName` - the same, but using Helidon abstraction of type names (may have type arguments)
- `Lookup` - a full search criteria for a registry lookup

# Startup

The following options are available to start a service registry (and the application):

1. Use API to create an `io.helidon.service.inject.InjectRegistryManager`
2. Use the Helidon startup class `io.helidon.Main`, which will use the injection main class through service loader
3. Use a generated main class, by default named `ApplicationMain` in the main package of the application (supports customization)

## Generated Main Class

To generate a main class, the Helidon Service Inject Maven plugin must be configured.
This is expected to be configured only for an application (i.e. not for library modules) - this is the reason we do not generate it automatically.

The generated main class will contain full, reflection less configuration of the service registry. It registers all services directly through API, and disables service discovery from classpath.

The Main class can also be customized; to do this:
1. Create a custom class (let's call it `CustomMain` as an example)
2. The class must extends the injection main class (`public abstract class CustomMain extends InjectionMain`)
3. The class must be annotated with `@Injection.Main`, so it is discovered by annotation processor
4. Implement any desired methods; the generated class will only implement `serviceDescriptors(InjectConfig.Builder configBuilder)` (always), and `discoverServices()` (if created from the Maven plugin)

For details on how to configure your build, see [Maven Plugin](../maven-plugin/README.md).

# Other

## API types quick reference
Expand Down
67 changes: 67 additions & 0 deletions service/inject/maven-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Maven Plugin
---

The Helidon Service Maven Plugin provides the following goals:

1. Create application artifacts (`create-application`, `create-test-application`)

# Create application artifacts Maven goals

This goal creates artifacts that are only valid for the service (assembled from libraries and its own sources).
This goal generates:

1. Application Binding - a mapping of services to injection points (to bypass runtime lookups) - generates class `Injection__Binding`
2. Application Main - a generated main class that registers all services (to bypass service discovery) - generates class `ApplicationMain`

Usage of this plugin goal is not required, yet it is recommended for final application module, it will add
- binding for injection points, to avoid runtime lookups
- explicit registration of all services into `InjectConfig`, to avoid resource lookup and reflection at runtime
- overall speedup of bootstrapping, as all the required tasks to start a service registry are code generated

This goal should not be used for library modules (i.e. modules that do not have a Main class that bootstraps registry).

## Usage

Goal names:

- `create-application` - for production sources
- `create-test-application` - for test sources (only creates binding, main class not relevant)

Configuration options:

| Name | Property | Default | Description |
|--------------------|-------------------------------------------------|------------------------|---------------------------------------------------------------------------------|
| `packageName` | `helidon.codegen.package-name` | Inferred from module | Package to put the generated classes in |
| `moduleName` | `helidon.codegen.module-name` | Inferred from module | Name of the JPMS module |
| `validate` | `helidon.inject.application.validate` | `true` | Whether to validate application |
| `createMain` | `helidon.inject.application.main.generate` | `true` | Whether to create application Main class |
| `mainClassName` | `helidon.inject.application.main.class.name` | `ApplicationMain` | Name of the generated Main class |
| `createBinding` | `helidon.inject.application.binding.generate` | `true` | Whether to create application binding |
| `bindingClassName` | `helidon.inject.application.binding.class.name` | `Application__Binding` | Name of the generated binding class, for test, it is `TestApplication__Binding` |
| `failOnError` | `helidon.inject.fail-on-error` | `true` | Whether to fail when the plugin encounters an error |
| `failOnWarning` | `helidon.inject.fail-on-warning` | `false` | Whether to fail when the plugin encounters a warning |
| `compilerArgs` | | | Arguments of the Java compiler (both classes are compiled by the plugin) |

Configuration example in `pom.xml`:

```xml

<plugin>
<groupId>io.helidon.service</groupId>
<artifactId>helidon-service-maven-plugin</artifactId>
<executions>
<execution>
<id>create-application</id>
<goals>
<goal>create-application</goal>
</goals>
</execution>
</executions>
<configuration>
<packageName>com.example.mypackage</packageName>
<bindingClassName>MyInjection__Binding</bindingClassName>
<mainClassName>MyApplicationMain</mainClassName>
<validate>false</validate>
</configuration>
</plugin>
```
41 changes: 41 additions & 0 deletions service/inject/maven-plugin/etc/spotbugs/exclude.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2024 Oracle and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<FindBugsFilter
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://github.com/spotbugs/filter/3.0.0"
xsi:schemaLocation="https://github.com/spotbugs/filter/3.0.0 https://raw.githubusercontent.com/spotbugs/spotbugs/3.1.0/spotbugs/etc/findbugsfilter.xsd">

<Match>
<!-- Path comes from config or code -->
<Class name="io.helidon.service.inject.maven.plugin.CreateApplicationAbstractMojo"/>
<Bug pattern="PATH_TRAVERSAL_IN"/>
</Match>
<Match>
<!-- Classpath is constructed from maven classpath -->
<Class name="io.helidon.service.inject.maven.plugin.CreateApplicationAbstractMojo"/>
<Bug pattern="DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED"/>
</Match>

<Match>
<!-- Path comes from config or code -->
<Class name="io.helidon.service.inject.maven.plugin.CreateTestApplicationMojo"/>
<Bug pattern="PATH_TRAVERSAL_IN"/>
</Match>
</FindBugsFilter>
203 changes: 203 additions & 0 deletions service/inject/maven-plugin/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2023, 2024 Oracle and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>io.helidon.service.inject</groupId>
<artifactId>helidon-service-inject-project</artifactId>
<version>4.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>helidon-service-inject-maven-plugin</artifactId>
<name>Helidon Service Maven Plugin</name>
<packaging>maven-plugin</packaging>

<properties>
<version.plexus.classworlds>2.7.0</version.plexus.classworlds>
<version.plexus.utils>3.3.0</version.plexus.utils>
<version.plugin.api>3.9.3</version.plugin.api>
<version.plugin.annotations>3.9.0</version.plugin.annotations>
<version.plugin.plugin>3.9.0</version.plugin.plugin>
<version.plugin.project>2.2.1</version.plugin.project>

<spotbugs.exclude>etc/spotbugs/exclude.xml</spotbugs.exclude>
</properties>

<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<reportSets>
<reportSet>
<reports>
<report>report</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>

<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>${version.plugin.api}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>${version.plugin.api}</version>
<scope>provided</scope>
</dependency>

<!-- normal dependencies -->
<dependency>
<groupId>io.helidon.common</groupId>
<artifactId>helidon-common</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.common</groupId>
<artifactId>helidon-common-types</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-class-model</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.service</groupId>
<artifactId>helidon-service-registry</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.service</groupId>
<artifactId>helidon-service-codegen</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.service.inject</groupId>
<artifactId>helidon-service-inject-codegen</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.service</groupId>
<artifactId>helidon-service-metadata</artifactId>
</dependency>
<dependency>
<!--
we cannot use helidon-service-inject as the SPI is required on classpath of application,
and this introduces conflicts; API is small and does not introduce SPI
that is used from within it, so we can share it
-->
<groupId>io.helidon.service.inject</groupId>
<artifactId>helidon-service-inject-api</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-scan</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-compiler</artifactId>
</dependency>
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>${version.plugin.api}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-classworlds</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>${version.plugin.annotations}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>${version.plugin.project}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>${version.plugin.plugin}</version>
<configuration>
<mojoDependencies>
<!-- we need this since 19ea is not really supported -->
<!-- <mojoDependency></mojoDependency>-->
</mojoDependencies>
<requiredMavenVersion>[3.6.1,)</requiredMavenVersion>
<requiredJavaVersion>[${version.java}.0,)</requiredJavaVersion>
</configuration>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
</plugins>
</build>

</project>
Loading

0 comments on commit c192431

Please sign in to comment.