Repository: openliberty/ci.maven
Issue: FeatureModifiedException occurring often with multi-module project

Using https://github.ibm.com/was-svt/acme-ee
Most attempts to generate features result in two calls to the binary scanner and a FeatureModifiedException.
This especially does not make sense for the initial call to the binary scanner as there are no current features passed to the binary scanner. And on calls made afterwards, the current features were all determined by binary scanner from the initial call.
Below is some debug output from running `mvn liberty:dev` (including changes from https://github.com/OpenLiberty/ci.common/pull/361 - also confirmed this error occurs without these changes)

Initial generate features on startup
```
[DEBUG] Calling binary-app-scanner-22.0.0.2-SNAPSHOT.jar with the following inputs...
  binaryInputs: [C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs11_m2\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs11_m1\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs20\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityPojoWSes\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityWeb\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3JAXWS\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3JAXWS_CDI\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3MDB\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3\\target\\classes]
  targetJavaEE: ee7
  targetMicroP: null
  currentFeatures: []
  logLocation: C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\target
  logLevel: *=FINE
  locale: en_CA
[DEBUG] Recalling binary scanner with the following inputs...
  binaryInputs: [C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs11_m2\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs11_m1\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs20\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityPojoWSes\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityWeb\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3JAXWS\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3JAXWS_CDI\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3MDB\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3\\target\\classes]
  targetJavaEE: ee7
  targetMicroP: null
  currentFeatures: []
  logLocation: C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\target
  logLevel: *=FINE
  locale: en_CA
[DEBUG] FeatureModifiedException, modifiedSet containsAll userFeatures, pass modifiedSet on to generateFeatures
[DEBUG] User defined features:[]
[DEBUG] Features detected by binary scanner which are not in server.xml[ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
...
...
...
[DEBUG] Created file C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\src\\main\\liberty\\config\\configDropins\\overrides\\generated-features.xml
[INFO] Generated the following features: [ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
```

Generate features after change to `acme-ee-main\\AcmeCommon\\src\\main\\java\\com\\ibm\\wssvt\\acme\\common\\bean\\StringConfigrable.java`
**FeatureModifiedException did not occur in this instance**
```
[DEBUG] Calling binary-app-scanner-22.0.0.2-SNAPSHOT.jar with the following inputs...
  binaryInputs: [C:\\Projects\\acme-ee-main\\AcmeCommon\\target\\classes]
  targetJavaEE: ee7
  targetMicroP: null
  currentFeatures: [ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
  logLocation: C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\target
  logLevel: *=FINE
  locale: en_CA
...
...
...
[DEBUG] Parsing the server file for features and includes: config\\server.xml
[DEBUG] User defined features:null
[DEBUG] Features detected by binary scanner which are not in server.xml[ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
[DEBUG] Xml document we'll try to update after generate features doc=io.openliberty.tools.common.plugins.config.ServerConfigXmlDocument@63e7de46 file=C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\src\\main\\liberty\\config\\server.xml
...
...
...
[DEBUG] Created file C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\src\\main\\liberty\\config\\configDropins\\overrides\\generated-features.xml
[INFO] Generated the following features: [ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
```

Generate features after change to `acme-ee-main\\AcmeAnnuityJAXRSCommon\\src\\main\\java\\com\\ibm\\wssvt\\acme\\annuity\\common\\business\\jaxrs\\MyJAXBResolver.java`
```
[DEBUG] Calling binary-app-scanner-22.0.0.2-SNAPSHOT.jar with the following inputs...
  binaryInputs: [C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSCommon\\target\\classes]
  targetJavaEE: ee7
  targetMicroP: null
  currentFeatures: [ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
  logLocation: C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\target
  logLevel: *=FINE
  locale: en_CA
[DEBUG] Recalling binary scanner with the following inputs...
  binaryInputs: [C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs11_m2\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs11_m1\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs20\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityPojoWSes\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityWeb\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3JAXWS\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3JAXWS_CDI\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3MDB\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3\\target\\classes]
  targetJavaEE: ee7
  targetMicroP: null
  currentFeatures: []
  logLocation: C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\target
  logLevel: *=FINE
  locale: en_CA
[DEBUG] Parsing the server file for features and includes: config\\server.xml
[DEBUG] FeatureModifiedException, modifiedSet containsAll userFeatures, pass modifiedSet on to generateFeatures
[DEBUG] Parsing the server file for features and includes: config\\server.xml
[DEBUG] User defined features:null
[DEBUG] Features detected by binary scanner which are not in server.xml[ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
[DEBUG] Xml document we'll try to update after generate features doc=io.openliberty.tools.common.plugins.config.ServerConfigXmlDocument@617cafc6 file=C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\src\\main\\liberty\\config\\server.xml
...
...
...
[DEBUG] Created file C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\src\\main\\liberty\\config\\configDropins\\overrides\\generated-features.xml
[INFO] Generated the following features: [ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
```

Generate features after change to `acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs20\\src\\main\\java\\com\\ibm\\wssvt\\acme\\annuity\\business\\impl\\jaxrs\\AnnuityMgmtSvcJAXRS.java`
```
[DEBUG] Calling binary-app-scanner-22.0.0.2-SNAPSHOT.jar with the following inputs...
  binaryInputs: [C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs20\\target\\classes]
  targetJavaEE: ee7
  targetMicroP: null
  currentFeatures: [ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
  logLocation: C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\target
  logLevel: *=FINE
  locale: en_CA
[DEBUG] Recalling binary scanner with the following inputs...
  binaryInputs: [C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs11_m2\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs11_m1\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSWSes_jaxrs20\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityJAXRSCommon\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityPojoWSes\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityWeb\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3JAXWS\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3JAXWS_CDI\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3MDB\\target\\classes, C:\\Projects\\acme-ee-main\\AcmeAnnuityEJB3\\target\\classes]
  targetJavaEE: ee7
  targetMicroP: null
  currentFeatures: []
  logLocation: C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\target
  logLevel: *=FINE
  locale: en_CA
[DEBUG] Parsing the server file for features and includes: config\\server.xml
[DEBUG] FeatureModifiedException, modifiedSet containsAll userFeatures, pass modifiedSet on to generateFeatures
[DEBUG] Parsing the server file for features and includes: config\\server.xml
[DEBUG] User defined features:null
[DEBUG] Features detected by binary scanner which are not in server.xml[ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
[DEBUG] Xml document we'll try to update after generate features doc=io.openliberty.tools.common.plugins.config.ServerConfigXmlDocument@ba05f301 file=C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\src\\main\\liberty\\config\\server.xml
...
...
...
[DEBUG] Created file C:\\Projects\\acme-ee-main\\AcmeWebEjbEar\\src\\main\\liberty\\config\\configDropins\\overrides\\generated-features.xml
[INFO] Generated the following features: [ejbLite-3.2, servlet-3.1, beanValidation-1.1, jndi-1.0, jaxws-2.2, jms-2.0, samlWeb-2.0, appSecurity-2.0, jaxrs-2.0, socialLogin-1.0, ejbRemote-3.2, jaxb-2.2, openidConnectServer-1.0, mdb-3.2, cdi-1.2, jpa-2.1]
```

Full debug output: [debugOutput.txt](https://github.com/OpenLiberty/ci.maven/files/8584560/debugOutput.txt)
 

Changed files:
liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/GenerateFeaturesMojo.java

diff --git a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/GenerateFeaturesMojo.java b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/GenerateFeaturesMojo.java
index dea8e295..52bb2cc3 100644
--- a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/GenerateFeaturesMojo.java
+++ b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/GenerateFeaturesMojo.java
@@ -200,16 +200,20 @@ public class GenerateFeaturesMojo extends ServerFeatureSupport {
             Set<String> userFeatures = (optimize) ? existingFeatures :
                 getServerFeatures(servUtil, generatedFiles, true); // user features excludes generatedFiles
             Set<String> modifiedSet = featuresModified.getFeatures(); // a set that works after being modified by the scanner
-
             if (modifiedSet.containsAll(userFeatures)) {
                 // none of the user features were modified, only features which were generated earlier.
-                log.debug("FeatureModifiedException, modifiedSet containsAll userFeatures, pass modifiedSet on to generateFeatures");
+                log.debug(
+                        "FeatureModifiedException, modifiedSet containsAll userFeatures, pass modifiedSet on to generateFeatures");
+                // features were modified to get a working set with the application's API usage, display warning to users and use modified set
+                log.warn(featuresModified.getMessage());
                 scannedFeatureList = modifiedSet;
             } else {
                 Set<String> allAppFeatures = featuresModified.getSuggestions(); // suggestions are scanned from binaries
                 allAppFeatures.addAll(userFeatures); // scanned plus configured features were detected to be in conflict
                 log.debug("FeatureModifiedException, combine suggestions from scanner with user features in error msg");
-                throw new MojoExecutionException(String.format(BinaryScannerUtil.BINARY_SCANNER_CONFLICT_MESSAGE1, allAppFeatures, modifiedSet));
+                throw new MojoExecutionException(
+                        String.format(BinaryScannerUtil.BINARY_SCANNER_CONFLICT_MESSAGE1, allAppFeatures, modifiedSet));
+
             }
         } catch (BinaryScannerUtil.RecommendationSetException showRecommendation) {
             if (showRecommendation.isExistingFeaturesConflict()) {