diff --git a/src/main/java/io/openliberty/tools/common/plugins/config/ServerConfigDocument.java b/src/main/java/io/openliberty/tools/common/plugins/config/ServerConfigDocument.java index 2ae4372f3..df3a36bd3 100644 --- a/src/main/java/io/openliberty/tools/common/plugins/config/ServerConfigDocument.java +++ b/src/main/java/io/openliberty/tools/common/plugins/config/ServerConfigDocument.java @@ -202,7 +202,7 @@ public ServerConfigDocument(CommonLoggerI log, File originalServerXMLFile, Map springBootAppNodeLocat this.springBootAppNodeLocation = springBootAppNodeLocation; } + /** + * Parses a loose application XML file and returns a list of all sourceOnDisk + * attribute values found on {@code } and {@code } elements. + * + * @param looseAppFile - the loose application XML file to parse + * @return a List of sourceOnDisk path strings; empty if none are found or the file cannot be parsed + * @throws FileNotFoundException if the file does not exist + * @throws IOException if the file cannot be read + */ + public static Set getSourceOnDiskPaths(File looseAppFile) throws FileNotFoundException, IOException { + Set result = new HashSet(); + Document doc; + try (FileInputStream is = new FileInputStream(looseAppFile)) { + doc = getDocumentBuilder().parse(is); + } catch (SAXException e) { + return result; // not valid XML + } + for (String tag : new String[]{"file", "dir"}) { + NodeList nodes = doc.getElementsByTagName(tag); + for (int i = 0; i < nodes.getLength(); i++) { + org.w3c.dom.Node attr = nodes.item(i).getAttributes().getNamedItem("sourceOnDisk"); + if (attr != null && !attr.getNodeValue().isEmpty()) { + result.add(attr.getNodeValue()); + } + } + } + return result; + } } \ No newline at end of file diff --git a/src/main/java/io/openliberty/tools/common/plugins/util/DevUtil.java b/src/main/java/io/openliberty/tools/common/plugins/util/DevUtil.java index a9e8b2b6c..96860eb91 100644 --- a/src/main/java/io/openliberty/tools/common/plugins/util/DevUtil.java +++ b/src/main/java/io/openliberty/tools/common/plugins/util/DevUtil.java @@ -5878,7 +5878,7 @@ protected void triggerMainModuleCompile(boolean testsOnly) throws IOException { /** * Trigger a compile of the entire specified module. This is only used in a - * multi-module scenario. Adds all Java files to the to be compiled list so that + * multi-module scenario. Adds all Java files to the to-be-compiled list so that * they will be compiled on next watch loop. * * @param project ProjectModule, the module to be compiled diff --git a/src/main/java/io/openliberty/tools/common/plugins/util/FeatureGeneratorUtil.java b/src/main/java/io/openliberty/tools/common/plugins/util/FeatureGeneratorUtil.java index c6d031ec2..98f17568d 100644 --- a/src/main/java/io/openliberty/tools/common/plugins/util/FeatureGeneratorUtil.java +++ b/src/main/java/io/openliberty/tools/common/plugins/util/FeatureGeneratorUtil.java @@ -16,6 +16,7 @@ package io.openliberty.tools.common.plugins.util; import java.io.File; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; @@ -26,6 +27,8 @@ import java.util.Map; import java.util.Set; +import io.openliberty.tools.common.plugins.config.ServerConfigDocument; + public abstract class FeatureGeneratorUtil { public static final String FEATURE_GEN_MAVEN_GROUP_ID = "com.ibm.websphere.appmod.tools"; @@ -135,6 +138,7 @@ public FeatureGeneratorUtil(File featureGen) { * @param currentFeatureSet - the features already specified in the server configuration * @param classFiles - a set of class files for the generator to handle. Should be a subset of allClassesDirectories * @param allClassesDirectories - the directories containing all the class files of the application + * @param looseConfigFilePath - the absolute path to the xml config of the loose application * @param logLocation - directory name relative to project or absolute path passed to feature generator * @param targetJavaEE - generate features valid for the indicated version of EE * @param targetMicroProfile - generate features valid for the indicated version of MicroProfile @@ -155,7 +159,7 @@ public FeatureGeneratorUtil(File featureGen) { * generator when used in combination with each other. E.g. EE 7 and MP 2.1 */ public Set runFeatureGenerator(Set currentFeatureSet, List classFiles, Set allClassesDirectories, - String logLocation, String targetJavaEE, String targetMicroProfile, Map featureListFileMap, boolean optimize) + String looseConfigFilePath, String logLocation, String targetJavaEE, String targetMicroProfile, Map featureListFileMap, boolean optimize) throws PluginExecutionException, NoRecommendationException, RecommendationSetException, FeatureModifiedException, FeatureUnavailableException, IllegalTargetException, IllegalTargetComboException, VersionlessFeatureDetectedException { Set generatedFeatureList = null; @@ -167,7 +171,8 @@ public Set runFeatureGenerator(Set currentFeatureSet, List binaryInputs = getBinaryInputs(classFiles, allClassesDirectories, optimize); + Set binaryInputs = getBinaryInputs(classFiles, allClassesDirectories, looseConfigFilePath, optimize); + String logLevel; if (isDebugEnabled()) { logLevel = "*=FINE"; // generate messages for debugging by support team @@ -384,9 +389,24 @@ private Method getGeneratorMethod() throws MalformedURLException, ClassNotFoundE return featureGenMethod; } - private static Set getBinaryInputs(List classFiles, Set classDirectories, boolean optimize) throws PluginExecutionException { + private Set getBinaryInputs(List classFiles, Set classDirectories, String looseConfigFilePath, boolean optimize) throws PluginExecutionException { Set resultSet; if (optimize) { + // Use either the loose app config or the class directories + if (looseConfigFilePath != null) { + try { + File looseAppFile = new File(looseConfigFilePath); + if (looseAppFile.exists()) { + resultSet = ServerConfigDocument.getSourceOnDiskPaths(looseAppFile); + if (!resultSet.isEmpty()) { + return resultSet; + } + } + } catch (IOException e) { + // if the app config is invalid try the class directories instead + } + warn("Application descriptor file not found while generating features, using class files instead: " + looseConfigFilePath); + } if (classDirectories == null || classDirectories.isEmpty()) { return new HashSet(); }