• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

evolvedbinary / elemental / 982

29 Apr 2025 08:34PM UTC coverage: 56.409% (+0.007%) from 56.402%
982

push

circleci

adamretter
[feature] Improve README.md badges

28451 of 55847 branches covered (50.94%)

Branch coverage included in aggregate %.

77468 of 131924 relevant lines covered (58.72%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.33
/exist-start/src/main/java/org/exist/start/CompatibleJavaVersionCheck.java
1
/*
2
 * Elemental
3
 * Copyright (C) 2024, Evolved Binary Ltd
4
 *
5
 * admin@evolvedbinary.com
6
 * https://www.evolvedbinary.com | https://www.elemental.xyz
7
 *
8
 * Use of this software is governed by the Business Source License 1.1
9
 * included in the LICENSE file and at www.mariadb.com/bsl11.
10
 *
11
 * Change Date: 2028-04-27
12
 *
13
 * On the date above, in accordance with the Business Source License, use
14
 * of this software will be governed by the Apache License, Version 2.0.
15
 *
16
 * Additional Use Grant: Production use of the Licensed Work for a permitted
17
 * purpose. A Permitted Purpose is any purpose other than a Competing Use.
18
 * A Competing Use means making the Software available to others in a commercial
19
 * product or service that: substitutes for the Software; substitutes for any
20
 * other product or service we offer using the Software that exists as of the
21
 * date we make the Software available; or offers the same or substantially
22
 * similar functionality as the Software.
23
 */
24
package org.exist.start;
25

26
import java.util.Optional;
27
import java.util.stream.Stream;
28

29
import static org.exist.start.CompatibleJavaVersionCheck.IncompatibleJavaVersion.IncompatibleJavaVersion;
30
import static org.exist.start.Main.ERROR_CODE_INCOMPATIBLE_JAVA_DETECTED;
31

32
public class CompatibleJavaVersionCheck {
×
33

34
    private static final IncompatibleJavaVersion[] INCOMPATIBLE_JAVA_VERSIONS = {
1✔
35
            IncompatibleJavaVersion(12),
1✔
36
            IncompatibleJavaVersion(13),
1✔
37
            IncompatibleJavaVersion(14),
1✔
38
            IncompatibleJavaVersion(15, 0, 2)
1✔
39
    };
40

41
    private static final String INCOMPATIBLE_JAVA_VERSION_NOTICE =
42
            "*****************************************************%n" +
43
            "Warning: Unreliable Java version has been detected!%n" +
44
            "%n" +
45
            "OpenJDK versions 12 through 15.0.1 suffer from a critical%n" +
46
            " bug in the JIT C2 compiler that will cause data loss in%n" +
47
            "Elemental.%n" +
48
            "%n" +
49
            "The problem has been reported to the OpenJDK community.%n" +
50
            "%n" +
51
            "For more information, see:%n" +
52
            "\t* https://bugs.openjdk.java.net/browse/JDK-8253191%n" +
53
            "\t* https://github.com/eXist-db/exist/issues/3375%n" +
54
            "%n" +
55
            "The detected version of Java on your system is: %s.%n" +
56
            "%n" +
57
            "To prevent potential data loss, Elemental will not be started.%n" +
58
            "To start Elemental, we recommend using Java 8 or 11.%n" +
59
            "*****************************************************";
60

61
    private static final Optional<String> RUNTIME_JAVA_VERSION = Optional.ofNullable(System.getProperty("java.version"));
1✔
62

63
    /**
64
     * Checks that the runtime version of Java is compatible.
65
     *
66
     * @throws StartException if the runtime version of Java is incompatible.
67
     */
68
    public static void checkForCompatibleJavaVersion() throws StartException {
69
        checkForCompatibleJavaVersion(RUNTIME_JAVA_VERSION);
×
70
    }
×
71

72
    static void checkForCompatibleJavaVersion(final Optional<String> checkJavaVersion) throws StartException {
73
        final Optional<int[]> maybeJavaVersionComponents = extractJavaVersionComponents(checkJavaVersion);
1✔
74

75
        if (!maybeJavaVersionComponents.isPresent()) {
1✔
76
            // Could not determine major java version, so best to let the user proceed...
77
            return;
1✔
78
        }
79

80
        // check for incompatible java version
81
        final int[] javaVersionComponents = maybeJavaVersionComponents.get();
1✔
82
        final int majorJavaVersion = javaVersionComponents[0];
1✔
83
        /* @Nullable */ final Integer minorJavaVersion = javaVersionComponents.length > 1 ? javaVersionComponents[1] : null;
1✔
84
        /* @Nullable */ final Integer patchJavaVersion = javaVersionComponents.length > 2 ? javaVersionComponents[2] : null;
1✔
85

86
        for (int i = 0; i < INCOMPATIBLE_JAVA_VERSIONS.length; i++) {
1✔
87
            final IncompatibleJavaVersion incompatibleJavaVersion = INCOMPATIBLE_JAVA_VERSIONS[i];
1✔
88

89
            // compare major versions
90
            if (majorJavaVersion == incompatibleJavaVersion.major) {
1✔
91

92
                // major version might be incompatible
93

94
                if (incompatibleJavaVersion.lessThanMinor != null && minorJavaVersion != null) {
1!
95
                    // compare minor version
96
                    if (minorJavaVersion >= incompatibleJavaVersion.lessThanMinor) {
1!
97
                        // minor version is compatible
98

99
                        if (incompatibleJavaVersion.lessThanPatch != null && patchJavaVersion != null) {
1!
100
                            // compare patch version
101
                            if (patchJavaVersion >= incompatibleJavaVersion.lessThanPatch) {
1✔
102
                                // patch version is compatible
103
                                continue;
1✔
104
                            }
105
                        }
106
                    }
107
                }
108

109
                // version is NOT compatible!
110
                throw new StartException(ERROR_CODE_INCOMPATIBLE_JAVA_DETECTED, String.format(INCOMPATIBLE_JAVA_VERSION_NOTICE, RUNTIME_JAVA_VERSION));
1✔
111
            }
112

113
            // version is compatible
114
        }
115
    }
1✔
116

117
    static Optional<int[]> extractJavaVersionComponents(final Optional<String> javaVersion) {
118
        return javaVersion
1✔
119
                .map(str -> str.split("\\.|_|-"))
1✔
120
                .filter(ary -> ary.length > 0)
1!
121
                .map(ary ->
1✔
122
                        Stream.of(ary)
1✔
123
                                .filter(str -> !str.isEmpty())
1!
124
                                .map(str -> { try { return Integer.parseInt(str); } catch (final NumberFormatException e) { return -1; }})
1✔
125
                                .filter(i -> i != -1)
1✔
126
                                .mapToInt(Integer::intValue)
1✔
127
                                .toArray()
1✔
128
                )
129
                .filter(ary -> ary.length > 0);
1!
130
    }
131

132
    static class IncompatibleJavaVersion {
133
        final int major;
134
        /* @Nullable */  final Integer lessThanMinor;
135
        /* @Nullable */ final Integer lessThanPatch;
136

137
        private IncompatibleJavaVersion(final int major, /* @Nullable */ Integer lessThanMinor, /* @Nullable */ Integer lessThanPatch) {
1✔
138
            this.major = major;
1✔
139
            this.lessThanMinor = lessThanMinor;
1✔
140
            this.lessThanPatch = lessThanPatch;
1✔
141
        }
1✔
142

143
        public static IncompatibleJavaVersion IncompatibleJavaVersion(final int major, /* @Nullable */ Integer lessThanMinor, /* @Nullable */ Integer lessThanPatch) {
144
            return new IncompatibleJavaVersion(major, lessThanMinor, lessThanPatch);
1✔
145
        }
146

147
        public static IncompatibleJavaVersion IncompatibleJavaVersion(final int major, /* @Nullable */ Integer lessThanMinor) {
148
            return IncompatibleJavaVersion(major, lessThanMinor, null);
×
149
        }
150

151
        public static IncompatibleJavaVersion IncompatibleJavaVersion(final int major) {
152
            return IncompatibleJavaVersion(major, null, null);
1✔
153
        }
154
    }
155
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc