Skip to content

Commit

Permalink
Feature 107: Support Java 9
Browse files Browse the repository at this point in the history
Added support of Java 9+ versions schema to Launch4j and Head
  • Loading branch information
skarpushin committed Apr 25, 2018
1 parent f118674 commit 120d709
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 22 deletions.
Binary file modified head/consolehead.o
Binary file not shown.
Binary file modified head/guihead.o
Binary file not shown.
Binary file modified head/head.o
Binary file not shown.
106 changes: 87 additions & 19 deletions head_src/head.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,27 +312,95 @@ BOOL regQueryValue(const char* regPath, unsigned char* buffer,
return result;
}

void formatJavaVersion(char* version, const char* originalVersion)
{
char* updatePart = strchr(originalVersion, '_');
int findNextVersionPart(const char* startAt) {
if (startAt == NULL || strlen(startAt) == 0) {
return 0;
}

if (updatePart != NULL)
{
// skip underscore
updatePart++;
char* firstSeparatorA = strchr(startAt, '.');
char* firstSeparatorB = strchr(startAt, '_');
char* firstSeparator;
if (firstSeparatorA == NULL) {
firstSeparator = firstSeparatorB;
} else if (firstSeparatorB == NULL) {
firstSeparator = firstSeparatorA;
} else {
firstSeparator = min(firstSeparatorA, firstSeparatorB);
}

if (strlen(updatePart) < 3)
{
const int majorVersionLength = updatePart - originalVersion;
strncpy(version, originalVersion, majorVersionLength);
*(version + majorVersionLength) = 0;
strcat(version, "0");
strcat(version, updatePart);
return;
}
}

strcpy(version, originalVersion);
if (firstSeparator == NULL) {
return strlen(startAt);
}

return firstSeparator - startAt;
}

/**
* This method will take java version from `originalVersion` string and convert/format it
* into `version` string that can be used for string comparison with other versions.
*
* Due to different version schemas <=8 vs. >=9 it will "normalize" versions to 1 format
* so we can directly compare old and new versions.
*/
#define JRE_VER_MAX_DIGITS_PER_PART 3
void formatJavaVersion(char* version, const char* originalVersion) {
strcpy(version, "");
if (originalVersion == NULL || strlen(originalVersion) == 0) {
return;
}

int partsAdded = 0;
int i;
char* pos = (char*) originalVersion;
int curPartLen;
while ((curPartLen = findNextVersionPart(pos)) > 0) {
char number[curPartLen + 1];
memset(number, 0, curPartLen + 1);
strncpy(number, pos, curPartLen);

if (partsAdded == 0 && (curPartLen != 1 || number[0] != '1')) {
// NOTE: When it's java 9+ we'll add "1" as the first part of the version
strcpy(version, "1");
partsAdded++;
}

if (partsAdded < 3) {
if (partsAdded > 0) {
strcat(version, ".");
}
for (i = 0;
(partsAdded > 0)
&& (i < JRE_VER_MAX_DIGITS_PER_PART - strlen(number));
i++) {
strcat(version, "0");
}
strcat(version, number);
} else if (partsAdded == 3) {
// add as an update
strcat(version, "_");
for (i = 0; i < JRE_VER_MAX_DIGITS_PER_PART - strlen(number); i++) {
strcat(version, "0");
}
strcat(version, number);
} else if (partsAdded == 4) {
// TODO: Add warning
break;
}
partsAdded++;

pos += curPartLen + 1;
if (pos >= originalVersion + strlen(originalVersion)) {
break;
}
}

for (i = partsAdded; i < 3; i++) {
strcat(version, ".");
int j;
for (j = 0; j < JRE_VER_MAX_DIGITS_PER_PART; j++) {
strcat(version, "0");
}
}
}

void regSearch(const char* keyName, const int searchType)
Expand Down
6 changes: 3 additions & 3 deletions src/net/sf/launch4j/config/Jre.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public class Jre implements IValidatable {
public static final String ARGS = "jvmArgs";

// __________________________________________________________________________________
public static final String VERSION_PATTERN = "(\\d\\.){2}\\d(_\\d+)?";

public static final String VERSION_PATTERN = "((\\d\\.){2}\\d(_\\d+)?)|(\\d+(\\.\\d+)*)";
public static final String JDK_PREFERENCE_JRE_ONLY = "jreOnly";
public static final String JDK_PREFERENCE_PREFER_JRE = "preferJre";
public static final String JDK_PREFERENCE_PREFER_JDK = "preferJdk";
Expand Down Expand Up @@ -116,7 +116,7 @@ public void checkInvariants() {
if (!Validator.isEmpty(maxVersion)) {
Validator.checkFalse(Validator.isEmpty(minVersion),
"jre.minVersion", Messages.getString("Jre.specify.min.version"));
Validator.checkTrue(minVersion.compareTo(maxVersion) < 0,
Validator.checkTrue(JreVersion.parseString(minVersion).compareTo(JreVersion.parseString(maxVersion)) < 0,
"jre.maxVersion", Messages.getString("Jre.max.greater.than.min"));
}
Validator.checkTrue(initialHeapSize == null || maxHeapSize != null,
Expand Down
121 changes: 121 additions & 0 deletions src/net/sf/launch4j/config/JreVersion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package net.sf.launch4j.config;

/**
* This class will abstract application from JRE versioning schema and provide
* comparing capabilities
*
* @author sergeyk
*
*/
public class JreVersion implements Comparable<JreVersion> {
private int x1;
private int x2;
private int x3;
private int x4;

public static JreVersion parseString(String versionStr) {
JreVersion ret = new JreVersion();
if (versionStr == null || versionStr.trim().length() == 0) {
return ret;
}
if (!versionStr.matches(Jre.VERSION_PATTERN)) {
// NOTE: This is actually shouldn't happen because version format had to be
// checked by Jre#checkInvariants BEFORE calling this method
throw new IllegalArgumentException("JRE version is not in a right format.");
}

String[] parts = versionStr.split("[\\._]");
int first = Integer.parseInt(parts[0]);
if (first >= 9) {
// java 9+ version schema
ret.x1 = 1;
ret.x2 = first;
if (parts.length >= 2) {
ret.x3 = Integer.parseInt(parts[1]);
if (parts.length >= 3) {
ret.x4 = Integer.parseInt(parts[2]);
}
}
} else {
// java <= 1.8 version schema
ret.x1 = first;

ret.x2 = Integer.parseInt(parts[1]);
ret.x3 = Integer.parseInt(parts[2]);
if (parts.length == 4) {
ret.x4 = Integer.parseInt(parts[3]);
}
}

return ret;
}

@Override
public String toString() {
if (x2 >= 9) {
return "" + x2 + "." + x3 + "." + x4;
}

return "" + x1 + "." + x2 + "." + x3 + (x4 > 0 ? "_" + x4 : "");
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x1;
result = prime * result + x2;
result = prime * result + x3;
result = prime * result + x4;
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
JreVersion other = (JreVersion) obj;
if (x1 != other.x1) {
return false;
}
if (x2 != other.x2) {
return false;
}
if (x3 != other.x3) {
return false;
}
if (x4 != other.x4) {
return false;
}
return true;
}

@Override
public int compareTo(JreVersion o) {
if (this.equals(o)) {
return 0;
}

if (x1 != o.x1) {
return x1 - o.x1;
}
if (x2 != o.x2) {
return x2 - o.x2;
}
if (x3 != o.x3) {
return x3 - o.x3;
}
if (x4 != o.x4) {
return x4 - o.x4;
}

throw new IllegalStateException("If you see this exception it means JreVersion::equals() method is buggy");
}
}

0 comments on commit 120d709

Please sign in to comment.