|
1 | 1 | /******************************************************************************* |
2 | | -* Copyright (c) 2017 Microsoft Corporation and others. |
| 2 | +* Copyright (c) 2017-2019 Microsoft Corporation and others. |
3 | 3 | * All rights reserved. This program and the accompanying materials |
4 | 4 | * are made available under the terms of the Eclipse Public License v1.0 |
5 | 5 | * which accompanies this distribution, and is available at |
|
15 | 15 | import java.io.FileOutputStream; |
16 | 16 | import java.io.IOException; |
17 | 17 | import java.io.UnsupportedEncodingException; |
| 18 | +import java.math.BigInteger; |
18 | 19 | import java.net.MalformedURLException; |
19 | 20 | import java.net.URI; |
20 | 21 | import java.net.URISyntaxException; |
|
45 | 46 | import com.microsoft.java.debug.core.protocol.Responses; |
46 | 47 | import com.microsoft.java.debug.core.protocol.Types; |
47 | 48 |
|
| 49 | +import sun.security.action.GetPropertyAction; |
| 50 | + |
48 | 51 | public class AdapterUtils { |
49 | 52 | private static final String OS_NAME = System.getProperty("os.name", "").toLowerCase(); |
50 | 53 | private static final Pattern ENCLOSING_CLASS_REGEX = Pattern.compile("^([^\\$]*)"); |
@@ -312,8 +315,9 @@ public static Path generateClasspathJar(String[] classPaths) throws IOException |
312 | 315 | Attributes attributes = manifest.getMainAttributes(); |
313 | 316 | attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0"); |
314 | 317 | // In jar manifest, the absolute path C:\a.jar should be converted to the url style file:///C:/a.jar |
315 | | - attributes.put(Attributes.Name.CLASS_PATH, String.join(" ", classpathUrls)); |
316 | | - Path tempfile = Files.createTempFile("classpath_", ".jar"); |
| 318 | + String classpathValue = String.join(" ", classpathUrls); |
| 319 | + attributes.put(Attributes.Name.CLASS_PATH, classpathValue); |
| 320 | + Path tempfile = createTempFile("cp_" + getMd5(classpathValue), ".jar"); |
317 | 321 | JarOutputStream jar = new JarOutputStream(new FileOutputStream(tempfile.toFile()), manifest); |
318 | 322 | jar.close(); |
319 | 323 |
|
@@ -338,9 +342,58 @@ public static Path generateArgfile(String[] classPaths, String[] modulePaths) th |
338 | 342 | } |
339 | 343 |
|
340 | 344 | argfile = argfile.replace("\\", "\\\\"); |
341 | | - Path tempfile = Files.createTempFile("java_", ".argfile"); |
| 345 | + Path tempfile = createTempFile("cp_" + getMd5(argfile), ".argfile"); |
342 | 346 | Files.write(tempfile, argfile.getBytes()); |
343 | 347 |
|
344 | 348 | return tempfile; |
345 | 349 | } |
| 350 | + |
| 351 | + private static Path tmpdir = null; |
| 352 | + |
| 353 | + private static synchronized Path getTmpDir() throws IOException { |
| 354 | + if (tmpdir == null) { |
| 355 | + try { |
| 356 | + tmpdir = Paths.get(java.security.AccessController.doPrivileged(new GetPropertyAction("java.io.tmpdir"))); |
| 357 | + } catch (NullPointerException | InvalidPathException e) { |
| 358 | + Path tmpfile = Files.createTempFile("", ".tmp"); |
| 359 | + tmpdir = tmpfile.getParent(); |
| 360 | + try { |
| 361 | + Files.deleteIfExists(tmpfile); |
| 362 | + } catch (Exception ex) { |
| 363 | + // do nothing |
| 364 | + } |
| 365 | + } |
| 366 | + } |
| 367 | + |
| 368 | + return tmpdir; |
| 369 | + } |
| 370 | + |
| 371 | + private static Path createTempFile(String baseName, String suffix) throws IOException { |
| 372 | + // loop until the temp file can be created |
| 373 | + SecurityManager sm = System.getSecurityManager(); |
| 374 | + for (int i = 0; ; i++) { |
| 375 | + Path tempFile = getTmpDir().resolve(baseName + (i == 0 ? "" : i) + suffix); |
| 376 | + try { |
| 377 | + // delete the old temp file |
| 378 | + Files.deleteIfExists(tempFile); |
| 379 | + } catch (Exception e) { |
| 380 | + // do nothing |
| 381 | + } |
| 382 | + |
| 383 | + if (!Files.exists(tempFile)) { |
| 384 | + return Files.createFile(tempFile); |
| 385 | + } |
| 386 | + } |
| 387 | + } |
| 388 | + |
| 389 | + private static String getMd5(String input) { |
| 390 | + try { |
| 391 | + MessageDigest md = MessageDigest.getInstance("MD5"); |
| 392 | + byte[] messageDigest = md.digest(input.getBytes()); |
| 393 | + BigInteger md5 = new BigInteger(1, messageDigest); |
| 394 | + return md5.toString(Character.MAX_RADIX); |
| 395 | + } catch (NoSuchAlgorithmException e) { |
| 396 | + return Integer.toString(input.hashCode(), Character.MAX_RADIX); |
| 397 | + } |
| 398 | + } |
346 | 399 | } |