diff --git a/pom.xml b/pom.xml
index 2267c88..f45f269 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.phsyberdome
phsyberdome-sca-cli
- 1.0.2-beta
+ 1.0.3-beta
jar
diff --git a/src/main/java/com/phsyberdome/drona/Plugins/JavaMavenPlugin.java b/src/main/java/com/phsyberdome/drona/Plugins/JavaMavenPlugin.java
index 599037b..a4c4f5c 100644
--- a/src/main/java/com/phsyberdome/drona/Plugins/JavaMavenPlugin.java
+++ b/src/main/java/com/phsyberdome/drona/Plugins/JavaMavenPlugin.java
@@ -11,6 +11,7 @@
import com.phsyberdome.drona.Models.Pair;
import com.phsyberdome.drona.Utils.FileUtil;
import com.phsyberdome.drona.Utils.MavenRepoHelper;
+import com.phsyberdome.drona.Utils.MavenVersionHelper;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
@@ -18,6 +19,9 @@
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;
@@ -41,9 +45,13 @@ public class JavaMavenPlugin implements PluginInterface
private ArrayList modules;
private final LicenseDetector licenseDetector;
+
+ private Set scannedDependencies;
+
public JavaMavenPlugin(LicenseDetector licenseDetector) {
this.licenseDetector = licenseDetector;
+ this.scannedDependencies = new HashSet<>();
}
@@ -77,7 +85,6 @@ public void readModules() {
String rootGroupId = MavenRepoHelper.extractAttributeFromNode(doc.getDocumentElement(), "groupId");
String rootVersion = MavenRepoHelper.extractAttributeFromNode(doc.getDocumentElement(), "version");
Module root = new Module(rootArtifactId,rootVersion);
-
NodeList list = doc.getElementsByTagName("dependency");
for(int i=0;i getModules() {
return modules;
}
+
+ private boolean alreadyScanned(Module m){
+ Iterator it = scannedDependencies.iterator();
+ while(it.hasNext()){
+ Module a = (Module) it.next();
+ if(a.getName()==m.getName() && a.getVersion() == m.getVersion()){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Module getScannedModule(Module m){
+ Iterator it = scannedDependencies.iterator();
+ while(it.hasNext()){
+ Module a = (Module) it.next();
+ if(a.getName().strip().equalsIgnoreCase(m.getName().strip()) && a.getVersion().strip().equalsIgnoreCase(m.getVersion().strip())){
+ return a;
+ }
+ }
+ return m;
+ }
+ private Module getScannedModule(String artifactId){
+ Iterator it = scannedDependencies.iterator();
+ while(it.hasNext()){
+ Module a = (Module) it.next();
+ if(a.getName().strip().equalsIgnoreCase(artifactId.strip())){
+ return a;
+ }
+ }
+ return new Module(artifactId,"");
+ }
+
+ private boolean isAlreadyScannedArtifact(String artifiactId) {
+ Iterator it = scannedDependencies.iterator();
+ while(it.hasNext()){
+ Module a = (Module) it.next();
+ if(a.getName().equalsIgnoreCase(artifiactId)){
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/src/main/java/com/phsyberdome/drona/Utils/FileUtil.java b/src/main/java/com/phsyberdome/drona/Utils/FileUtil.java
index 4b8180f..ee789fb 100644
--- a/src/main/java/com/phsyberdome/drona/Utils/FileUtil.java
+++ b/src/main/java/com/phsyberdome/drona/Utils/FileUtil.java
@@ -156,7 +156,7 @@ public static Path getFilePathFromURL(String path, String cloneLocation){
return null;
}
- public static File downloadFile(String path, String url){
+ public static File downloadFile(String path, String url)throws IOException{
File file = FileSystems.getDefault().getPath(path).toFile();
if(file.exists()) {
FileUtil.deleteDirectory(file);
@@ -164,11 +164,8 @@ public static File downloadFile(String path, String url){
try {
FileUtils.copyURLToFile(new URL(url), file);
} catch (MalformedURLException ex) {
- Logger.getLogger(MavenRepoHelper.class.getName()).log(Level.SEVERE, null, ex);
+// Logger.getLogger(MavenRepoHelper.class.getName()).log(Level.SEVERE, null, ex);
return null;
- } catch (IOException ex) {
- Logger.getLogger(MavenRepoHelper.class.getName()).log(Level.SEVERE, null, ex);
- return null;
}
return file;
}
@@ -218,10 +215,10 @@ public static String readFile(Path filePath) {
text = content.collect(Collectors.joining("\n"));
}
return text;
- } catch (IOException ex) {
+ } catch (Exception ex) {
CLIHelper.updateCurrentLine(ex.getLocalizedMessage(), Ansi.Color.RED);
- return null;
}
+ return "";
}
public static void extractZipFolder(String zipFile,String extractFolder)
@@ -334,7 +331,7 @@ public static void extractTarball(String tarfile,String toPath) throws FileNotFo
tarEntry = tarIn.getNextTarEntry();
}
tarIn.close();
- }catch(IOException e){
+ }catch(Exception e){
CLIHelper.updateCurrentLine("Failed to untar file " + tarfile,Ansi.Color.RED);
}
diff --git a/src/main/java/com/phsyberdome/drona/Utils/JSONHelper.java b/src/main/java/com/phsyberdome/drona/Utils/JSONHelper.java
index 416a3f9..a4aa03a 100644
--- a/src/main/java/com/phsyberdome/drona/Utils/JSONHelper.java
+++ b/src/main/java/com/phsyberdome/drona/Utils/JSONHelper.java
@@ -5,15 +5,14 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.phsyberdome.drona.CLIHelper;
import com.phsyberdome.drona.Models.Pair;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import org.fusesource.jansi.Ansi;
/**
*
@@ -27,7 +26,7 @@ public static String convertToJson(Object object) {
try {
json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
}catch(JsonProcessingException e) {
- Logger.getLogger(JSONHelper.class.getCanonicalName()).log(Level.WARNING, e.getLocalizedMessage());
+ CLIHelper.updateCurrentLine("Failed to convert to json!", Ansi.Color.RED);
return null;
}
return json;
@@ -38,7 +37,7 @@ public static T convertToObj(Class c,String json) {
ObjectMapper objectMapper = new ObjectMapper();
return (T) objectMapper.readValue(json, c);
}catch(Exception e) {
- Logger.getLogger(JSONHelper.class.getCanonicalName()).log(Level.WARNING, e.getLocalizedMessage());
+ CLIHelper.updateCurrentLine("Failed to parse json!", Ansi.Color.RED);
}
return null;
}
@@ -49,8 +48,8 @@ public static String getValue(String keyPath,String json){
try {
root = objectMapper.readTree(json);
return root.at(keyPath).asText();
- } catch (JsonProcessingException ex) {
- Logger.getLogger(JSONHelper.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (Exception e){
+ CLIHelper.updateCurrentLine("Failed to parse json!", Ansi.Color.RED);
}
return null;
}
@@ -68,8 +67,8 @@ public static List getValues(String keyPath,String json){
res.add(field.getKey());
}
return res;
- } catch (JsonProcessingException ex) {
- Logger.getLogger(JSONHelper.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (Exception ex) {
+ CLIHelper.updateCurrentLine("Failed to parse json!", Ansi.Color.RED);
}
return null;
}
diff --git a/src/main/java/com/phsyberdome/drona/Utils/MavenRepoHelper.java b/src/main/java/com/phsyberdome/drona/Utils/MavenRepoHelper.java
index dd59ec2..e251c21 100644
--- a/src/main/java/com/phsyberdome/drona/Utils/MavenRepoHelper.java
+++ b/src/main/java/com/phsyberdome/drona/Utils/MavenRepoHelper.java
@@ -4,6 +4,7 @@
import com.phsyberdome.drona.CLIHelper;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
@@ -61,11 +62,19 @@ public static Document readXMLDocument(Path path) {
- public static Document getMavenMetadataDocument(String groupId, String artifactId) {
+ public static Document getMavenMetadataDocument(String groupId, String artifactId){
String repoUrl = buildRootRepoUrl(groupId, artifactId);
String mvnMetadataFileUrl = repoUrl + "maven-metadata.xml";
- File metadataFile = FileUtil.downloadFile("/.drona/temp/data/metadata.xml", mvnMetadataFileUrl);
+ File metadataFile;
+ try {
+ metadataFile = FileUtil.downloadFile("/.drona/temp/data/metadata.xml", mvnMetadataFileUrl);
+ } catch (IOException ex) {
+ return null;
+ }
+ if(metadataFile==null) {
+ return null;
+ }
Document doc = readXMLDocument(metadataFile.toPath());
if(metadataFile.exists()){
FileUtil.deleteDirectory(metadataFile);
@@ -135,7 +144,6 @@ public static String getVersionFromParent(String artifactId,Document doc){
public static Document getParentPOM(Document pom) {
NodeList parents = pom.getElementsByTagName("parent");
if(parents.getLength() <= 0){
- System.out.println("This is the root pom!");
return null;
}
Element parent = (Element) parents.item(0);
@@ -144,7 +152,12 @@ public static Document getParentPOM(Document pom) {
String version = parent.getElementsByTagName("version").item(0).getTextContent();
//version = resolvePropertyValue(version, pom);
String urlToParentPom = buildUrlForPomFile(groupId, artifactId, version);
- File file = FileUtil.downloadFile("/.drona/temp/poms/pom.xml", urlToParentPom);
+ File file;
+ try {
+ file = FileUtil.downloadFile("/.drona/temp/poms/"+artifactId+"_parent_pom.xml", urlToParentPom);
+ } catch (IOException ex) {
+ return null;
+ }
Document doc = readXMLDocument(file.toPath());
if(file.exists()){
FileUtil.deleteDirectory(file);
diff --git a/src/main/java/com/phsyberdome/drona/Utils/MavenVersion.java b/src/main/java/com/phsyberdome/drona/Utils/MavenVersion.java
new file mode 100644
index 0000000..4d78f9f
--- /dev/null
+++ b/src/main/java/com/phsyberdome/drona/Utils/MavenVersion.java
@@ -0,0 +1,52 @@
+
+
+package com.phsyberdome.drona.Utils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * @author Pratham Gahlout
+ */
+
+
+public class MavenVersion {
+
+ private List ranges;
+
+ public MavenVersion(MavenVersionRange... ranges) {
+ this.ranges = new ArrayList<>();
+ for(var range:ranges) {
+ this.ranges.add(range);
+ }
+ }
+
+ public MavenVersion(List ranges) {
+ this.ranges = ranges;
+ }
+
+ public boolean isSatisfied(String version) {
+ boolean isSatisfied = false;
+
+ for(var range:ranges) {
+ isSatisfied |= range.isSatisfied(version);
+ }
+
+ return isSatisfied;
+ }
+
+ @Override
+ public String toString() {
+ return ranges.stream()
+ .map(MavenVersionRange::toString)
+ .collect(Collectors.joining(""));
+ }
+
+
+
+
+}
diff --git a/src/main/java/com/phsyberdome/drona/Utils/MavenVersionHelper.java b/src/main/java/com/phsyberdome/drona/Utils/MavenVersionHelper.java
index 690f56d..1480b99 100644
--- a/src/main/java/com/phsyberdome/drona/Utils/MavenVersionHelper.java
+++ b/src/main/java/com/phsyberdome/drona/Utils/MavenVersionHelper.java
@@ -11,6 +11,7 @@
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.annotation.Nullable;
import org.fusesource.jansi.Ansi;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -23,13 +24,16 @@
*/
public class MavenVersionHelper {
- public static String softVersionRegex = "(?[\\d.\\D]+)";
- public static String hardVersionRegex = "(?:^\\[(?[\\d.\\D]+)\\]$)";
- public static String conditionalVersionRegex = "(?:(?(?<=\\]|\\)),(?=\\[|\\())|,|(?:(?<=,)(?:(?[\\d.\\D]+)\\]|(?[\\d.]+)\\)))|(?:(?:\\[(?[\\d.]+)|\\((?[\\d.]+))(?=,)))+";
+// public static String softVersionRegex = "(?[\\d.\\D]+)";
+// public static String hardVersionRegex = "(?:^\\[(?[\\d.\\D]+)\\]$)";
+// public static String conditionalVersionRegex = "(?:(?(?<=\\]|\\)),(?=\\[|\\())|,|(?:(?<=,)(?:(?[\\d.\\D]+)\\]|(?[\\d.]+)\\)))|(?:(?:\\[(?[\\d.]+)|\\((?[\\d.]+))(?=,)))+";
public static List getAllVersions(String groupId,String artifactId) {
- Document document = MavenRepoHelper.getMavenMetadataDocument(groupId, artifactId);
+ @Nullable Document document = MavenRepoHelper.getMavenMetadataDocument(groupId, artifactId);
+ if(document == null) {
+ return new ArrayList<>();
+ }
NodeList list = document.getElementsByTagName("version");
List versions = new ArrayList();
for(int i=0;i getAllVersions(String groupId,String artifactId) {
}
public static String resolveVersion(String groupId,String artifactId,String version) {
+ if(version.length() == 0 || isPureVersion(version)) {
+ return version;
+ }
ArrayList allVersions = (ArrayList) getAllVersions(groupId, artifactId);
+ if(allVersions.isEmpty()) {
+ return version;
+ }
+ List ranges = extractRanges(version);
+ MavenVersion versionSpec = new MavenVersion(ranges);
+ List satisfiedVersions = new ArrayList<>();
+ try {
+ for(var v: allVersions) {
+ if(versionSpec.isSatisfied(v)){
+ satisfiedVersions.add(v);
+ }
+ }
+ List semverVersions = new ArrayList<>();
+ for(var s: satisfiedVersions) {
+ semverVersions.add(new Semver(s,Semver.SemverType.NPM));
+ }
+ Collections.sort(semverVersions);
+ return !semverVersions.isEmpty()? semverVersions.get(semverVersions.size()-1).toString() : version;
+ } catch (SemverException ex) {
+ return version;
+ }
+ }
+
+ private static List extractRanges(String version) {
+ List ranges = new ArrayList<>();
+
+ Pattern combinationOfVersionPattern = Pattern.compile("(?[\\[(]([\\d\\W\\w]\\.?)*,([\\d\\W\\w]\\.?)*[\\])])(?,)(?[\\[(]([\\d\\W\\w]\\.?)*,(\\d\\.?)*[\\])])");
+ Matcher matcher = combinationOfVersionPattern.matcher(version);
try {
- Pattern pattern = Pattern.compile(softVersionRegex+"|"+hardVersionRegex+"|"+conditionalVersionRegex,Pattern.CASE_INSENSITIVE);
- Matcher matcher = pattern.matcher(version);
-
- if(matcher.find()){
- if(matcher.group("eq") != null){
- return matcher.group("eq");
- }else if(matcher.group("heq")!=null){
- return matcher.group("heq");
- }else if(matcher.group("lte")!=null){
- if(matcher.group("gte") !=null) {
- }else {
- allVersions.removeIf(s -> {
- try {
- Semver version1 = new Semver(s,Semver.SemverType.IVY);
- Semver version2 = new Semver(matcher.group("lte"), Semver.SemverType.IVY);
- return version1.isGreaterThan(version2);
- }catch(SemverException e){
- System.out.println("not following semantic version "+s);
- return false;
- }
- });
- return allVersions.get(allVersions.size()-1);
- }
- }else if(matcher.group("gte")!=null){
+ if(matcher.matches()){
+ matcher.reset();
+ while(matcher.find()){
+ String versionLeft = matcher.group("versionLeft");
+ String versionRight = matcher.group("versionRight");
+ // now this will cause duplication of mavenversionrange in the list,
+ // we can make it comparable and thus avoid adding the same range again,
+ // anyways we dont care right now because its not going to be a very long list
+ System.out.println(versionLeft + "," + versionRight);
+ ranges.add(MavenVersionRange.parse(versionLeft));
+ ranges.add(MavenVersionRange.parse(versionRight));
}
-
- else if(matcher.group("gte")!=null && matcher.group("lt")!=null){
-
- }else if(matcher.group("gt")!=null && matcher.group("lt")!=null){
-
+ if(ranges.isEmpty()){
+ // Means no matches for combination of ranges
+ ranges.add(MavenVersionRange.parse(version));
+ System.out.println(MavenVersionRange.parse(version));
}
+
}else {
- CLIHelper.updateCurrentLine("Regex failed to match", Ansi.Color.RED);
+ ranges.add(MavenVersionRange.parse(version));
}
- }catch(IllegalStateException e){
- return version;
+ } catch(Exception e) {
+ CLIHelper.updateCurrentLine("Failed to resolve version!", Ansi.Color.RED);
}
- return version;
+
+ return ranges;
}
+ private static boolean isPureVersion(String version) {
+ return !version.contains("(")
+ || !version.contains(")")
+ || !version.contains("]")
+ || !version.contains("[")
+ || !version.contains(".");
+ }
}
diff --git a/src/main/java/com/phsyberdome/drona/Utils/MavenVersionRange.java b/src/main/java/com/phsyberdome/drona/Utils/MavenVersionRange.java
new file mode 100644
index 0000000..9e7ebd0
--- /dev/null
+++ b/src/main/java/com/phsyberdome/drona/Utils/MavenVersionRange.java
@@ -0,0 +1,114 @@
+
+
+package com.phsyberdome.drona.Utils;
+
+import com.vdurmont.semver4j.Semver;
+import com.vdurmont.semver4j.SemverException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ *
+ * @author Pratham Gahlout
+ */
+class MavenVersionRange {
+ private boolean isLeftClosedInterval = false;
+ private boolean isRightClosedInterval = false;
+ private String A;
+ private String B;
+
+ private MavenVersionRange(String A, boolean isHard) {
+ this.A = A;
+ this.B = A;
+ isLeftClosedInterval = isHard;
+ isRightClosedInterval = isHard;
+ }
+
+ private MavenVersionRange(String A, String B, boolean isLeftClosed, boolean isRightClosed) {
+ this.A = A;
+ this.B = B;
+ isLeftClosedInterval = isLeftClosed;
+ isRightClosedInterval = isRightClosed;
+ }
+
+
+ public static MavenVersionRange parse(String version) throws Exception {
+ Pattern pattern = Pattern.compile(",");
+ Matcher matcher = pattern.matcher(version);
+
+ if(matcher.find()){
+ // This is a range. This only supports a single range and not a combination of ranges
+ // so we assume the occurance of ',' will only be one time
+ Pattern rangeMatchPattern = Pattern.compile("[(\\[](?([\\d\\w\\W]\\.?)*),(?([\\d\\w\\W]\\.?)*)[\\])]");
+ Matcher rangeMatch = rangeMatchPattern.matcher(version);
+ if(rangeMatch.matches()){
+ var isLeftClosed = !version.contains("(");
+ var isRightClosed = !version.contains(")");
+ var leftInterval = rangeMatch.group("left");
+ var rightInterval = rangeMatch.group("right");
+ leftInterval = leftInterval.isBlank() ? "0" : leftInterval;
+ rightInterval = rightInterval.isBlank() ? "999999" : rightInterval;
+ return new MavenVersionRange(leftInterval,rightInterval,isLeftClosed,isRightClosed);
+ }else {
+ // Throw invalid version exception
+ throw new Exception();
+ }
+
+ }else {
+ // Its either a soft requirement or a hard requirement
+ if(version.endsWith("]")){
+ // its a hard requirement
+ return new MavenVersionRange(version.replaceAll("\\]","").replaceAll("\\[", ""), true);
+ }else {
+ // its a soft requirement
+ return new MavenVersionRange(version,false);
+ }
+ }
+ }
+
+ public boolean isSatisfied(String version) throws SemverException{
+ Semver leftInterval = new Semver(A, Semver.SemverType.NPM);
+ Semver rightInterval = new Semver(B, Semver.SemverType.NPM);
+ Semver versionToCompare = new Semver(version, Semver.SemverType.NPM);
+ if(leftInterval.isEqualTo(rightInterval)) {
+ return versionToCompare.isEqualTo(leftInterval);
+ }else {
+ if(isLeftClosedInterval && isRightClosedInterval) {
+ // Means a hard req
+
+ return versionToCompare.isGreaterThanOrEqualTo(leftInterval)
+ && versionToCompare.isLowerThanOrEqualTo(rightInterval);
+ }else if(isLeftClosedInterval) {
+ return versionToCompare.isGreaterThanOrEqualTo(leftInterval)
+ && versionToCompare.isLowerThan(rightInterval);
+ }else if(isRightClosedInterval) {
+ return versionToCompare.isGreaterThan(leftInterval)
+ && versionToCompare.isLowerThanOrEqualTo(rightInterval);
+ }else {
+ return versionToCompare.isGreaterThan(leftInterval)
+ && versionToCompare.isLowerThan(rightInterval);
+ }
+ }
+
+ }
+
+ @Override
+ public String toString() {
+ String str = "";
+ str += isLeftClosedInterval ? "[" : "(";
+ str += A + ",";
+ str += B;
+ str += isRightClosedInterval ? "]" : ")";
+ return str;
+ }
+
+ public boolean equals(MavenVersionRange obj) {
+ return this.isLeftClosedInterval == obj.isLeftClosedInterval
+ && this.isRightClosedInterval == obj.isRightClosedInterval
+ && this.A.equals(obj.A)
+ && this.B.equals(obj.B);
+ }
+
+
+
+}
diff --git a/src/main/java/com/phsyberdome/drona/licensedetector/LicenseDatabase.java b/src/main/java/com/phsyberdome/drona/licensedetector/LicenseDatabase.java
index 7d79e66..3e62a47 100644
--- a/src/main/java/com/phsyberdome/drona/licensedetector/LicenseDatabase.java
+++ b/src/main/java/com/phsyberdome/drona/licensedetector/LicenseDatabase.java
@@ -114,8 +114,10 @@ private void downloadLicenseListData(){
pathToLicenseListJSON = pathToLicenseList.toString();
} catch (MalformedURLException ex) {
Logger.getLogger(LicenseDatabase.class.getName()).log(Level.SEVERE, null, ex);
+ System.exit(0);
} catch (IOException ex) {
Logger.getLogger(LicenseDatabase.class.getName()).log(Level.SEVERE, null, ex);
+ System.exit(0);
}
CLIHelper.printLine("License data downloaded at "+pathToLicenseListJSON.toString(), Color.GREEN);
diff --git a/src/test/java/com/phsyberdome/drona/Utils/MavenVersionHelperTest.java b/src/test/java/com/phsyberdome/drona/Utils/MavenVersionHelperTest.java
index 69866f8..92d3879 100644
--- a/src/test/java/com/phsyberdome/drona/Utils/MavenVersionHelperTest.java
+++ b/src/test/java/com/phsyberdome/drona/Utils/MavenVersionHelperTest.java
@@ -56,9 +56,9 @@ public void testResolveVersion() {
System.out.println("resolveVersion");
String groupId = "com.fasterxml.jackson.core";
String artifactId = "jackson-databind";
-// String version = "(,2.4.0-rc4]";
- String version = "2.4.0-rc3";
- String expResult = "2.4.0-rc3";
+ String version = "[2.16.0,2.17.0-rc1)";
+// String version = "2.4.0-rc3";
+ String expResult = "2.16.1";
String result = MavenVersionHelper.resolveVersion(groupId,artifactId,version);
assertEquals(expResult,result);
}