diff --git a/java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java b/java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java index f6b43ef53a50..eaa9d18b1507 100644 --- a/java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java +++ b/java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,8 @@ */ package com.intellij.openapi.roots.libraries; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; -import com.intellij.openapi.projectRoots.JdkUtil; import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderEntry; @@ -27,8 +27,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.util.List; import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.Manifest; public class JarVersionDetectionUtil { private JarVersionDetectionUtil() { } @@ -39,7 +43,7 @@ public class JarVersionDetectionUtil { if (library instanceof LibraryOrderEntry) { VirtualFile jar = LibrariesHelper.getInstance().findJarByClass(((LibraryOrderEntry)library).getLibrary(), detectionClass); if (jar != null && jar.getFileSystem() instanceof JarFileSystem) { - return JdkUtil.getJarMainAttribute(jar, Attributes.Name.IMPLEMENTATION_VERSION); + return getMainAttribute(jar, Attributes.Name.IMPLEMENTATION_VERSION); } } } @@ -51,7 +55,21 @@ public class JarVersionDetectionUtil { public static String detectJarVersion(@NotNull String detectionClass, @NotNull List files) { VirtualFile jarRoot = LibrariesHelper.getInstance().findRootByClass(files, detectionClass); return jarRoot != null && jarRoot.getFileSystem() instanceof JarFileSystem ? - JdkUtil.getJarMainAttribute(jarRoot, Attributes.Name.IMPLEMENTATION_VERSION) : null; + getMainAttribute(jarRoot, Attributes.Name.IMPLEMENTATION_VERSION) : null; + } + + private static String getMainAttribute(VirtualFile jarRoot, Attributes.Name attribute) { + VirtualFile manifestFile = jarRoot.findFileByRelativePath(JarFile.MANIFEST_NAME); + if (manifestFile != null) { + try (InputStream stream = manifestFile.getInputStream()) { + return new Manifest(stream).getMainAttributes().getValue(attribute); + } + catch (IOException e) { + Logger.getInstance(JarVersionDetectionUtil.class).debug(e); + } + } + + return null; } @Nullable @@ -63,4 +81,4 @@ public class JarVersionDetectionUtil { public static String getImplementationVersion(@NotNull File jar) { return JarUtil.getJarAttribute(jar, Attributes.Name.IMPLEMENTATION_VERSION); } -} +} \ No newline at end of file diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java index de869f41e983..dfbc5b8b0598 100644 --- a/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java +++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java @@ -28,8 +28,8 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.openapi.util.io.JarUtil; import com.intellij.openapi.util.text.StringUtilRt; -import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.encoding.EncodingManager; import com.intellij.util.PathUtil; @@ -64,57 +64,52 @@ public class JdkUtil { * see IDEA-126859 for additional details */ public static final String PROPERTY_DO_NOT_ESCAPE_CLASSPATH_URL = "idea.do.not.escape.classpath.url"; + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.projectRoots.JdkUtil"); private static final String WRAPPER_CLASS = "com.intellij.rt.execution.CommandLineWrapper"; private JdkUtil() { } /** - * @return the specified attribute of the JDK (examines rt.jar) or null if cannot determine the value + * Returns the specified attribute of the JDK (examines rt.jar), or {@code null} if cannot determine the value. */ @Nullable - public static String getJdkMainAttribute(@NotNull Sdk jdk, Attributes.Name attribute) { - VirtualFile homeDirectory = jdk.getHomeDirectory(); - - VirtualFile rtJar = null; - if (homeDirectory != null) { - rtJar = homeDirectory.findFileByRelativePath("jre/lib/rt.jar"); // JDK - if (rtJar == null) rtJar = homeDirectory.findFileByRelativePath("lib/rt.jar"); // JRE - if (rtJar == null) rtJar = homeDirectory.findFileByRelativePath("jre/lib/vm.jar"); // IBM JDK - if (rtJar == null) rtJar = homeDirectory.findFileByRelativePath("../Classes/classes.jar"); // Apple JDK - } - - if (rtJar == null) { - if (attribute == Attributes.Name.IMPLEMENTATION_VERSION) { - String versionString = jdk.getVersionString(); - if (versionString != null) { - final int start = versionString.indexOf("\""); - final int end = versionString.lastIndexOf("\""); - versionString = start >= 0 && (end > start) ? versionString.substring(start + 1, end) : null; + public static String getJdkMainAttribute(@NotNull Sdk jdk, @NotNull Attributes.Name attribute) { + if (attribute == Attributes.Name.IMPLEMENTATION_VERSION) { + // optimization: JDK version string is cached + String versionString = jdk.getVersionString(); + if (versionString != null) { + int start = versionString.indexOf('"'), end = versionString.lastIndexOf('"'); + if (start >= 0 && end > start) { + return versionString.substring(start + 1, end); } - return versionString; - } - else { - return null; } } - VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(rtJar); - return jarRoot != null ? getJarMainAttribute(jarRoot, attribute) : null; + String homePath = jdk.getHomePath(); + if (homePath != null) { + File signatureJar = FileUtil.findFirstThatExist( + homePath + "/jre/lib/rt.jar", + homePath + "/lib/rt.jar", + homePath + "/jre/lib/vm.jar", + homePath + "/../Classes/classes.jar", + homePath + "/jrt-fs.jar"); + if (signatureJar != null) { + return JarUtil.getJarAttribute(signatureJar, attribute); + } + } + + return null; } + /** @deprecated to be removed in IDEA 2018 */ @Nullable - public static String getJarMainAttribute(@NotNull VirtualFile jarRoot, Attributes.Name attribute) { + @SuppressWarnings("unused") + public static String getJarMainAttribute(@NotNull VirtualFile jarRoot, @NotNull Attributes.Name attribute) { VirtualFile manifestFile = jarRoot.findFileByRelativePath(JarFile.MANIFEST_NAME); if (manifestFile != null) { - try { - InputStream stream = manifestFile.getInputStream(); - try { - return new Manifest(stream).getMainAttributes().getValue(attribute); - } - finally { - stream.close(); - } + try (InputStream stream = manifestFile.getInputStream()) { + return new Manifest(stream).getMainAttributes().getValue(attribute); } catch (IOException e) { LOG.debug(e);