|
1 | 1 | package org.mcphackers.mcp.tools; |
2 | 2 |
|
| 3 | +import org.mcphackers.mcp.MCP; |
| 4 | +import org.mcphackers.mcp.tasks.mode.TaskParameter; |
| 5 | + |
3 | 6 | import java.awt.Desktop; |
4 | 7 | import java.awt.Toolkit; |
5 | 8 | import java.awt.datatransfer.StringSelection; |
6 | 9 | import java.io.BufferedInputStream; |
7 | 10 | import java.io.BufferedReader; |
| 11 | +import java.io.BufferedWriter; |
8 | 12 | import java.io.ByteArrayOutputStream; |
9 | 13 | import java.io.File; |
10 | 14 | import java.io.IOException; |
|
14 | 18 | import java.net.URISyntaxException; |
15 | 19 | import java.nio.file.Files; |
16 | 20 | import java.nio.file.Path; |
| 21 | +import java.nio.file.Paths; |
17 | 22 | import java.security.MessageDigest; |
18 | 23 | import java.security.NoSuchAlgorithmException; |
| 24 | +import java.util.ArrayList; |
| 25 | +import java.util.HashMap; |
| 26 | +import java.util.List; |
| 27 | +import java.util.Map; |
19 | 28 | import java.util.Objects; |
20 | 29 | import java.util.concurrent.ExecutorService; |
21 | 30 | import java.util.concurrent.Executors; |
22 | 31 | import java.util.concurrent.Future; |
23 | 32 |
|
24 | 33 | public abstract class Util { |
25 | 34 | public static final ExecutorService SINGLE_THREAD_EXECUTOR = Executors.newSingleThreadExecutor(); |
| 35 | + public static final Map<String, Integer> javaToJavaVersion = new HashMap<>(); |
26 | 36 |
|
27 | 37 | public static int runCommand(String[] cmd, Path dir, boolean killOnShutdown) throws IOException { |
28 | 38 | ProcessBuilder procBuilder = new ProcessBuilder(cmd); |
@@ -204,16 +214,70 @@ public static String getJava() { |
204 | 214 | return System.getProperties().getProperty("java.home") + File.separator + "bin" + File.separator + "java"; |
205 | 215 | } |
206 | 216 |
|
207 | | - public static int getJavaVersion() { |
208 | | - String javaVersion = System.getProperty("java.version"); |
209 | | - String[] versionParts = javaVersion.split("\\."); |
210 | | - int versionNumber = Integer.parseInt(versionParts[0]); |
| 217 | + public static int getJavaVersion(MCP mcp) { |
| 218 | + String javaHome = getJava(); |
| 219 | + if (mcp == null) { |
| 220 | + String javaVersion = System.getProperty("java.version"); |
| 221 | + String[] versionParts = javaVersion.split("\\."); |
| 222 | + int versionNumber = Integer.parseInt(versionParts[0]); |
211 | 223 |
|
212 | | - if (versionNumber < 9) { |
213 | | - versionNumber = Integer.parseInt(versionParts[1]); |
| 224 | + if (versionNumber < 9) { |
| 225 | + versionNumber = Integer.parseInt(versionParts[1]); |
| 226 | + } else { |
| 227 | + versionNumber = Integer.parseInt(versionParts[0]); |
| 228 | + } |
| 229 | + javaToJavaVersion.put(javaHome, versionNumber); |
| 230 | + return versionNumber; |
214 | 231 | } else { |
215 | | - versionNumber = Integer.parseInt(versionParts[0]); |
| 232 | + // TODO: This is a hack |
| 233 | + // Please refactor. |
| 234 | + javaHome = mcp.getOptions().getStringParameter(TaskParameter.JAVA_HOME); |
| 235 | + Path javac = Paths.get(javaHome).resolve("bin").resolve("javac"); |
| 236 | + int javaVersion; |
| 237 | + if (!Files.exists(javac)) { |
| 238 | + javaVersion = 6; |
| 239 | + javaToJavaVersion.put(javaHome, javaVersion); |
| 240 | + return javaVersion; |
| 241 | + } |
| 242 | + |
| 243 | + String tempDirPath = System.getProperty("java.io.tmpdir"); |
| 244 | + |
| 245 | + // Write and compile a temporary Java file, then use ASM to read the default class file |
| 246 | + // version. |
| 247 | + try { |
| 248 | + Path tempJavaSrc = Files.createTempFile("retromcp-javac-check-", ".java"); |
| 249 | + Path tempJavaOut = tempJavaSrc.getParent().resolve("Main.class"); |
| 250 | + try (BufferedWriter writer = Files.newBufferedWriter(tempJavaSrc)) { |
| 251 | + writer.write("class Main { }\n"); |
| 252 | + } |
| 253 | + |
| 254 | + // Compile tempJavaSrc using the set javaHome |
| 255 | + List<String> cmd = new ArrayList<>(); |
| 256 | + cmd.add(javac.toAbsolutePath().toString()); |
| 257 | + cmd.add(tempJavaSrc.toAbsolutePath().toString()); |
| 258 | + cmd.add("-d"); |
| 259 | + cmd.add(tempDirPath); |
| 260 | + |
| 261 | + int exitCode = Util.runCommand(cmd.toArray(new String[] {}), Paths.get(tempDirPath), true); |
| 262 | + if (exitCode != 0) { |
| 263 | + throw new RuntimeException("Failed to compile a test program with: " + javaHome); |
| 264 | + } |
| 265 | + |
| 266 | + if (!Files.exists(tempJavaOut)) { |
| 267 | + throw new IllegalStateException("Test program could not be found at the location it was supposed to!"); |
| 268 | + } |
| 269 | + |
| 270 | + // Read class version from class |
| 271 | + int classVersion = ClassUtils.getClassVersion(tempJavaOut); |
| 272 | + return ClassUtils.getSourceFromClassVersion(classVersion); |
| 273 | + } catch (IOException ignored) { |
| 274 | + } |
| 275 | + |
| 276 | + return 6; |
216 | 277 | } |
217 | | - return versionNumber; |
| 278 | + } |
| 279 | + |
| 280 | + public static int getJavaVersion() { |
| 281 | + return getJavaVersion(null); |
218 | 282 | } |
219 | 283 | } |
0 commit comments