diff --git a/service/tests/inject/codegen/src/test/java/io/helidon/service/tests/inject/codegen/InjectCodegenTypesTest.java b/service/tests/inject/codegen/src/test/java/io/helidon/service/tests/inject/codegen/InjectCodegenTypesTest.java
index c221515bca2..5856b589df5 100644
--- a/service/tests/inject/codegen/src/test/java/io/helidon/service/tests/inject/codegen/InjectCodegenTypesTest.java
+++ b/service/tests/inject/codegen/src/test/java/io/helidon/service/tests/inject/codegen/InjectCodegenTypesTest.java
@@ -24,10 +24,16 @@
import java.util.Set;
import io.helidon.common.types.TypeName;
+import io.helidon.service.inject.Binding;
+import io.helidon.service.inject.InjectConfig;
+import io.helidon.service.inject.InjectRegistryManager;
+import io.helidon.service.inject.InjectionMain;
+import io.helidon.service.inject.InjectionPlanBinder;
import io.helidon.service.inject.api.Event;
import io.helidon.service.inject.api.EventManager;
import io.helidon.service.inject.api.FactoryType;
import io.helidon.service.inject.api.GeneratedInjectService;
+import io.helidon.service.inject.api.InjectRegistry;
import io.helidon.service.inject.api.InjectServiceDescriptor;
import io.helidon.service.inject.api.Injection;
import io.helidon.service.inject.api.Interception;
@@ -85,6 +91,7 @@ void testTypes() {
checkField(toCheck, checked, fields, "INJECTION_SCOPE_HANDLER", Injection.ScopeHandler.class);
checkField(toCheck, checked, fields, "INJECTION_SERVICES_FACTORY", Injection.ServicesFactory.class);
checkField(toCheck, checked, fields, "INJECTION_QUALIFIED_FACTORY", Injection.QualifiedFactory.class);
+ checkField(toCheck, checked, fields, "INJECTION_MAIN", Injection.Main.class);
// api.Interception.*
checkField(toCheck, checked, fields, "INTERCEPTION_INTERCEPTED", Interception.Intercepted.class);
@@ -97,6 +104,13 @@ void testTypes() {
checkField(toCheck, checked, fields, "INJECT_INJECTION_POINT", Ip.class);
checkField(toCheck, checked, fields, "INJECT_SERVICE_INSTANCE", ServiceInstance.class);
checkField(toCheck, checked, fields, "INJECT_SERVICE_DESCRIPTOR", InjectServiceDescriptor.class);
+ checkField(toCheck, checked, fields, "INJECT_CONFIG", InjectConfig.class);
+ checkField(toCheck, checked, fields, "INJECT_CONFIG_BUILDER", InjectConfig.Builder.class);
+ checkField(toCheck, checked, fields, "INJECT_MAIN", InjectionMain.class);
+ checkField(toCheck, checked, fields, "INJECT_BINDING", Binding.class);
+ checkField(toCheck, checked, fields, "INJECT_REGISTRY", InjectRegistry.class);
+ checkField(toCheck, checked, fields, "INJECT_REGISTRY_MANAGER", InjectRegistryManager.class);
+ checkField(toCheck, checked, fields, "INJECT_PLAN_BINDER", InjectionPlanBinder.class);
// api.* interception types
checkField(toCheck, checked, fields, "INTERCEPT_EXCEPTION", InterceptionException.class);
@@ -132,6 +146,9 @@ void testTypes() {
checkField(toCheck, checked, fields, "INTERCEPT_G_WRAPPER_QUALIFIED_FACTORY",
GeneratedInjectService.QualifiedFactoryInterceptionWrapper.class);
+ checkField(toCheck, checked, fields, "STRING_ARRAY", String[].class);
+ checkField(toCheck, checked, fields, "DOUBLE_ARRAY", double[].class);
+
assertThat("If the collection is not empty, please add appropriate checkField line to this test",
toCheck,
IsEmptyCollection.empty());
diff --git a/service/tests/inject/inject/pom.xml b/service/tests/inject/inject/pom.xml
index 3d483dca7b4..7768e2efaf7 100644
--- a/service/tests/inject/inject/pom.xml
+++ b/service/tests/inject/inject/pom.xml
@@ -137,6 +137,22 @@
+
+ io.helidon.service.inject
+ helidon-service-inject-maven-plugin
+ ${helidon.version}
+
+
+ create-application
+
+ create-application
+
+
+
+
+ true
+
+
diff --git a/service/tests/inject/inject/src/main/java/io/helidon/service/tests/inject/CustomMain.java b/service/tests/inject/inject/src/main/java/io/helidon/service/tests/inject/CustomMain.java
new file mode 100644
index 00000000000..41fff4325b6
--- /dev/null
+++ b/service/tests/inject/inject/src/main/java/io/helidon/service/tests/inject/CustomMain.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+package io.helidon.service.tests.inject;
+
+import io.helidon.service.inject.InjectConfig;
+import io.helidon.service.inject.InjectionMain;
+import io.helidon.service.inject.api.InjectRegistry;
+import io.helidon.service.inject.api.Injection;
+
+/**
+ * Example of a custom main class.
+ * This class is here to make sure this does not get broken.
+ */
+@Injection.Main
+public abstract class CustomMain extends InjectionMain {
+ /*
+ Important note:
+ DO NOT change the signature of methods in this class, as that would cause a backward incompatible change
+ for our users.
+ The subtype is code generated. Any changes in the
+ Helidon APIs would cause older generated code to stop working.
+ The only exception is major version updates, but it would still be better if this stays compatible.
+ */
+
+ @Override
+ protected void beforeServiceDescriptors(InjectConfig.Builder configBuilder) {
+ System.out.println("Before service descriptors");
+ }
+
+ @Override
+ protected void afterServiceDescriptors(InjectConfig.Builder configBuilder) {
+ System.out.println("After service descriptors");
+ }
+
+ @Override
+ protected InjectRegistry init(InjectConfig config) {
+ System.out.println("Before init method");
+ try {
+ return super.init(config);
+ } finally {
+ System.out.println("After init method");
+ }
+ }
+
+ @Override
+ protected void start(String[] arguments) {
+ super.start(arguments);
+ }
+
+ @Override
+ protected InjectConfig.Builder configBuilder(String[] arguments) {
+ return super.configBuilder(arguments);
+ }
+}
diff --git a/service/tests/inject/inject/src/test/java/io/helidon/service/tests/inject/MainClassTest.java b/service/tests/inject/inject/src/test/java/io/helidon/service/tests/inject/MainClassTest.java
new file mode 100644
index 00000000000..82cc105a13c
--- /dev/null
+++ b/service/tests/inject/inject/src/test/java/io/helidon/service/tests/inject/MainClassTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+package io.helidon.service.tests.inject;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import io.helidon.service.inject.InjectConfig;
+
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+// test that the generated main class exists and works as expected
+public class MainClassTest {
+ @Test
+ public void testMain() throws NoSuchMethodException {
+ // this class is expected to be code generated based on CustomMain @Injection.Main annotation
+ ApplicationMain appMain = new ApplicationMain();
+
+ assertThat(appMain, instanceOf(CustomMain.class));
+
+ Class theClass = ApplicationMain.class;
+
+ assertThat("The class must be public, to be a candidate for Main class",
+ Modifier.isPublic(theClass.getModifiers()));
+
+ // the class must have the following two methods (when not using the maven plugin):
+ // public static void main(String[] args) {}
+ // protected void serviceDescriptors(InjectConfig.Builder config) {}
+ Method mainMethod = theClass.getMethod("main", String[].class);
+ assertThat("The main method must be public", Modifier.isPublic(mainMethod.getModifiers()));
+ assertThat("The main method must be static", Modifier.isStatic(mainMethod.getModifiers()));
+ assertThat("The main method must return void", mainMethod.getReturnType(), equalTo(void.class));
+
+ Method serviceDescriptorMethod = theClass.getDeclaredMethod("serviceDescriptors", InjectConfig.Builder.class);
+ assertThat("The service descriptors method must be protected",
+ Modifier.isProtected(serviceDescriptorMethod.getModifiers()));
+ assertThat("The service descriptors method must not be static",
+ !Modifier.isStatic(serviceDescriptorMethod.getModifiers()));
+ assertThat("The service descriptors method must return void",
+ serviceDescriptorMethod.getReturnType(),
+ equalTo(void.class));
+ }
+}
diff --git a/service/tests/inject/lookup/pom.xml b/service/tests/inject/lookup/pom.xml
index 4ee6d85a335..1d1be68d387 100644
--- a/service/tests/inject/lookup/pom.xml
+++ b/service/tests/inject/lookup/pom.xml
@@ -137,6 +137,22 @@
+
+ io.helidon.service.inject
+ helidon-service-inject-maven-plugin
+ ${helidon.version}
+
+
+ create-application
+
+ create-application
+
+
+
+
+ true
+
+
diff --git a/service/tests/inject/qualified-providers/pom.xml b/service/tests/inject/qualified-providers/pom.xml
index 0772cf44a96..e00b45ef4c1 100644
--- a/service/tests/inject/qualified-providers/pom.xml
+++ b/service/tests/inject/qualified-providers/pom.xml
@@ -127,6 +127,22 @@
+
+ io.helidon.service.inject
+ helidon-service-inject-maven-plugin
+ ${helidon.version}
+
+
+ create-application
+
+ create-application
+
+
+
+
+ true
+
+
diff --git a/service/tests/inject/toolbox/pom.xml b/service/tests/inject/toolbox/pom.xml
index 5cc2a7b0322..84c7f654273 100644
--- a/service/tests/inject/toolbox/pom.xml
+++ b/service/tests/inject/toolbox/pom.xml
@@ -141,6 +141,22 @@
+
+ io.helidon.service.inject
+ helidon-service-inject-maven-plugin
+ ${helidon.version}
+
+
+ create-application
+
+ create-application
+
+
+
+
+ true
+
+
diff --git a/service/tests/inject/toolbox/src/test/java/io/helidon/service/tests/inject/toolbox/ToolBoxTest.java b/service/tests/inject/toolbox/src/test/java/io/helidon/service/tests/inject/toolbox/ToolBoxTest.java
index 5e9b9a6a023..974c976e4c0 100644
--- a/service/tests/inject/toolbox/src/test/java/io/helidon/service/tests/inject/toolbox/ToolBoxTest.java
+++ b/service/tests/inject/toolbox/src/test/java/io/helidon/service/tests/inject/toolbox/ToolBoxTest.java
@@ -150,7 +150,6 @@ void hierarchyOfInjections() {
* This assumes the presence of module(s) + application(s) to handle all bindings, with effectively no lookups!
*/
@Test
- @Disabled("Disabled, as this required maven plugin, to be added in a later PR")
void noServiceActivationRequiresLookupWhenApplicationIsPresent() {
Counter counter = lookupCounter();
long initialCount = counter.count();