diff --git a/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java b/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java index 89f802a4569c..444aabd57a27 100644 --- a/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java +++ b/platform/bootstrap/src/com/intellij/ide/BootstrapClassLoaderUtil.java @@ -56,11 +56,11 @@ public class BootstrapClassLoaderUtil extends ClassUtilCore { public static UrlClassLoader initClassLoader(boolean updatePlugins) throws Exception { PathManager.loadProperties(); - List classpathElements = new ArrayList(); - addParentClasspath(classpathElements); - addIDEALibraries(classpathElements); - addAdditionalClassPath(classpathElements); - UrlClassLoader newClassLoader = new UrlClassLoader(filterClassPath(classpathElements), null, true, true); + List classpath = new ArrayList(); + addParentClasspath(classpath); + addIDEALibraries(classpath); + addAdditionalClassPath(classpath); + UrlClassLoader newClassLoader = UrlClassLoader.build().urls(filterClassPath(classpath)).allowLock().useCache().get(); // prepare plugins if (updatePlugins && !isLoadingOfExternalPluginsDisabled()) { diff --git a/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java b/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java index 81fa6d5fe753..e5e0e9685658 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java +++ b/platform/core-impl/src/com/intellij/ide/plugins/cl/PluginClassLoader.java @@ -47,7 +47,7 @@ public class PluginClassLoader extends UrlClassLoader { final PluginId pluginId, final String version, final File pluginRoot) { - super(urls, null, true, true); + super(build().urls(urls).allowLock().useCache()); myParents = parents; myPluginId = pluginId; myPluginVersion = version; diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java index 7ce253cd727d..d9d6916cceb0 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java @@ -270,7 +270,7 @@ public class ExternalSystemApiUtil { } return result; } - + @SuppressWarnings("unchecked") @NotNull public static Collection> getChildren(@NotNull DataNode node, @NotNull Key key) { @@ -341,7 +341,7 @@ public class ExternalSystemApiUtil { } }); } - + public static void executeOnEdt(boolean synchronous, @NotNull Runnable task) { if (synchronous) { if (ApplicationManager.getApplication().isDispatchThread()) { @@ -393,7 +393,7 @@ public class ExternalSystemApiUtil { * * This method allows to differentiate between them (e.g. we don't want to change language level when new module is imported to * an existing project). - * + * * @return true if new project is being imported; false if new module is being imported */ public static boolean isNewProjectConstruction() { @@ -441,7 +441,7 @@ public class ExternalSystemApiUtil { * module. *

* This method tries to find root project's config path assuming that given path points to a sub-project's config path. - * + * * @param externalProjectPath external sub-project's config path * @param externalSystemId target external system * @param project target ide project @@ -554,17 +554,17 @@ public class ExternalSystemApiUtil { /** * There is a possible case that methods of particular object should be executed with classpath different from the one implied - * by the current class' classloader. External system offers {@link ParametersEnhancer#enhanceLocalProcessing(List)} method + * by the current class' class loader. External system offers {@link ParametersEnhancer#enhanceLocalProcessing(List)} method * for defining that custom classpath. *

* It's also possible that particular implementation of {@link ParametersEnhancer} is compiled using dependency to classes * which are provided by the {@link ParametersEnhancer#enhanceLocalProcessing(List) expanded classpath}. E.g. a class * 'A' might use method of class 'B' and 'A' is located at the current (system/plugin) classpath but - * 'B' is not. We need to reload 'A' using its expanded classpath then, i.e. create new classloaded + * 'B' is not. We need to reload 'A' using its expanded classpath then, i.e. create new class loaded * with that expanded classpath and load 'A' by it. *

* This method allows to do that. - * + * * @param clazz custom classpath-aware class which instance should be created (is assumed to have a no-args constructor) * @param target type * @return newly created instance of the given class loaded by custom classpath-aware loader @@ -591,7 +591,7 @@ public class ExternalSystemApiUtil { //noinspection unchecked urls.addAll((Collection)method.invoke(baseLoader)); } - UrlClassLoader loader = new UrlClassLoader(urls, baseLoader.getParent()) { + UrlClassLoader loader = new UrlClassLoader(UrlClassLoader.build().urls(urls).parent(baseLoader.getParent())) { @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { if (name.equals(clazz.getName())) { diff --git a/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java b/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java index 87ff2b97a27e..1f1eef51630a 100644 --- a/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java +++ b/platform/platform-impl/src/com/intellij/ui/win/RecentTasks.java @@ -32,8 +32,7 @@ public class RecentTasks { static { final String libraryName = (System.getProperty("sun.arch.data.model").contains("64"))? - "jumplistbridge64.dll": - "jumplistbridge.dll"; + "jumpListBridge64.dll": "jumpListBridge.dll"; final String binPath = PathManager.getBinPath(); final String communityBinPath = PathManager.getHomePath() + File.separatorChar + "community" + File.separatorChar + "bin"; diff --git a/platform/util/src/com/intellij/util/lang/ClassPath.java b/platform/util/src/com/intellij/util/lang/ClassPath.java index b0f13f91c02e..31037cf6ab0e 100644 --- a/platform/util/src/com/intellij/util/lang/ClassPath.java +++ b/platform/util/src/com/intellij/util/lang/ClassPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.util.lang; import com.intellij.openapi.application.PathManager; @@ -96,11 +95,17 @@ public class ClassPath { } } + /** @deprecated use {@link #ClassPath(java.util.List, boolean, boolean, boolean, boolean)} (to remove in IDEA 14) */ public ClassPath(URL[] urls, boolean canLockJars, boolean canUseCache) { - this(urls, canLockJars, canUseCache, false, true); + this(Arrays.asList(urls), canLockJars, canUseCache, false, true); } + /** @deprecated use {@link #ClassPath(java.util.List, boolean, boolean, boolean, boolean)} (to remove in IDEA 14) */ public ClassPath(URL[] urls, boolean canLockJars, boolean canUseCache, boolean acceptUnescapedUrls, boolean preloadJarContents) { + this(Arrays.asList(urls), canLockJars, canUseCache, acceptUnescapedUrls, preloadJarContents); + } + + public ClassPath(List urls, boolean canLockJars, boolean canUseCache, boolean acceptUnescapedUrls, boolean preloadJarContents) { myCanLockJars = canLockJars; myCanUseCache = canUseCache; myAcceptUnescapedUrls = acceptUnescapedUrls; @@ -110,7 +115,17 @@ public class ClassPath { // Accessed by reflection from PluginClassLoader // TODO: do we need it? void addURL(URL url) { - push(new URL[]{url}); + push(Collections.singletonList(url)); + } + + private void push(List urls) { + if (!urls.isEmpty()) { + synchronized (myUrls) { + for (int i = urls.size() - 1; i >= 0; i--) { + myUrls.push(urls.get(i)); + } + } + } } @Nullable @@ -229,14 +244,6 @@ public class ClassPath { return loader; } - private void push(URL[] urls) { - if (urls.length == 0) return; - synchronized (myUrls) { - for (int i = urls.length - 1; i >= 0; i--) myUrls.push(urls[i]); - - } - } - private class MyEnumeration implements Enumeration { private int myIndex = 0; private Resource myRes = null; diff --git a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java index 4158c352532f..43ef2cd611bb 100644 --- a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java +++ b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java @@ -36,41 +36,76 @@ import java.util.List; public class UrlClassLoader extends ClassLoader { @NonNls static final String CLASS_EXTENSION = ".class"; - private final ClassPath myClassPath; + public static final class Builder { + private List myURLs = ContainerUtil.emptyList(); + private ClassLoader myParent = null; + private boolean myLockJars = false; + private boolean myUseCache = false; + private boolean myAcceptUnescaped = false; + private boolean myPreload = true; + + private Builder() { } + + public Builder urls(List urls) { myURLs = urls; return this; } + public Builder urls(URL... urls) { myURLs = Arrays.asList(urls); return this; } + public Builder parent(ClassLoader parent) { myParent = parent; return this; } + public Builder allowLock() { myLockJars = true; return this; } + public Builder allowLock(boolean lockJars) { myLockJars = lockJars; return this; } + public Builder useCache() { myUseCache = true; return this; } + public Builder useCache(boolean useCache) { myUseCache = useCache; return this; } + public Builder allowUnescaped() { myAcceptUnescaped = true; return this; } + public Builder noPreload() { myPreload = false; return this; } + public UrlClassLoader get() { return new UrlClassLoader(this); } + } + + public static Builder build() { + return new Builder(); + } + private final List myURLs; + private final ClassPath myClassPath; + /** @deprecated use {@link #build()} (to remove in IDEA 14) */ public UrlClassLoader(@NotNull ClassLoader parent) { - this(Arrays.asList(((URLClassLoader)parent).getURLs()), parent.getParent(), true, true); + this(build().urls(((URLClassLoader)parent).getURLs()).parent(parent.getParent()).allowLock().useCache()); } + /** @deprecated use {@link #build()} (to remove in IDEA 14) */ public UrlClassLoader(List urls, @Nullable ClassLoader parent) { - this(urls, parent, false, false); + this(build().urls(urls).parent(parent)); } + /** @deprecated use {@link #build()} (to remove in IDEA 14) */ public UrlClassLoader(URL[] urls, @Nullable ClassLoader parent) { - this(Arrays.asList(urls), parent, false, false); + this(build().urls(urls).parent(parent)); } - public UrlClassLoader(List urls, @Nullable ClassLoader parent, boolean canLockJars, boolean canUseCache) { - this(urls, parent, canLockJars, canUseCache, false, true); + /** @deprecated use {@link #build()} (to remove in IDEA 14) */ + public UrlClassLoader(List urls, @Nullable ClassLoader parent, boolean lockJars, boolean useCache) { + this(build().urls(urls).parent(parent).allowLock(lockJars).useCache(useCache)); } - public UrlClassLoader(List urls, - @Nullable ClassLoader parent, - boolean canLockJars, - boolean canUseCache, - boolean acceptUnescapedUrls, - boolean preloadJarContents) { + /** @deprecated use {@link #build()} (to remove in IDEA 14) */ + public UrlClassLoader(List urls, @Nullable ClassLoader parent, boolean lockJars, boolean useCache, boolean allowUnescaped, boolean preload) { super(parent); - - List list = ContainerUtil.map(urls, new Function() { + myURLs = ContainerUtil.map(urls, new Function() { @Override public URL fun(URL url) { return internProtocol(url); } }); - myClassPath = new ClassPath(list.toArray(new URL[list.size()]), canLockJars, canUseCache, acceptUnescapedUrls, preloadJarContents); - myURLs = list; + myClassPath = new ClassPath(myURLs, lockJars, useCache, allowUnescaped, preload); + } + + protected UrlClassLoader(@NotNull Builder builder) { + super(builder.myParent); + myURLs = ContainerUtil.map(builder.myURLs, new Function() { + @Override + public URL fun(URL url) { + return internProtocol(url); + } + }); + myClassPath = new ClassPath(myURLs, builder.myLockJars, builder.myUseCache, builder.myAcceptUnescaped, builder.myPreload); } public static URL internProtocol(@NotNull URL url) { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntInstallation.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntInstallation.java index 3b4a28971f13..f07283b52347 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntInstallation.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntInstallation.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -30,7 +30,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; -import java.util.Collections; import java.util.Comparator; import java.util.Properties; @@ -117,11 +116,11 @@ public class AntInstallation { public String getVersion() { return VERSION.get(myProperties); } - + public String getHomeDir() { return HOME_DIR.get(myProperties); } - + public AbstractProperty.AbstractPropertyContainer getProperties() { return myProperties; } @@ -134,7 +133,7 @@ public class AntInstallation { public void updateClasspath() { myClassLoaderHolder.updateClasspath(); } - + public static AntInstallation fromHome(String homePath) throws ConfigurationException { File antHome = new File(homePath); String antPath = "'" + antHome.getAbsolutePath() + "'"; @@ -166,7 +165,7 @@ public class AntInstallation { Properties properties = new Properties(); InputStream stream = null; try { - stream = new UrlClassLoader(Collections.singletonList(antJar.toURL()), null, false, false, true, false).getResourceAsStream(VERSION_RESOURCE); + stream = UrlClassLoader.build().urls(antJar.toURI().toURL()).allowUnescaped().noPreload().get().getResourceAsStream(VERSION_RESOURCE); properties.load(stream); } catch (MalformedURLException e) { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntResourcesClassLoader.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntResourcesClassLoader.java index feb9356add33..c5ee60111e04 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntResourcesClassLoader.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntResourcesClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -31,7 +31,7 @@ public class AntResourcesClassLoader extends UrlClassLoader { private final Set myMisses = new THashSet(); public AntResourcesClassLoader(final List urls, final ClassLoader parentLoader, final boolean canLockJars, final boolean canUseCache) { - super(urls, parentLoader, canLockJars, canUseCache, true, false); + super(build().urls(urls).parent(parentLoader).allowLock(canLockJars).useCache(canUseCache).allowUnescaped().noPreload()); } protected Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException { diff --git a/plugins/devkit/src/actions/ShowSerializedXmlAction.java b/plugins/devkit/src/actions/ShowSerializedXmlAction.java index e6280912535c..9de4276ddefb 100644 --- a/plugins/devkit/src/actions/ShowSerializedXmlAction.java +++ b/plugins/devkit/src/actions/ShowSerializedXmlAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -99,9 +99,9 @@ public class ShowSerializedXmlAction extends DumbAwareAction { LOG.info(e1); } } - + final Project project = module.getProject(); - UrlClassLoader loader = new UrlClassLoader(urls, XmlSerializer.class.getClassLoader()); + UrlClassLoader loader = UrlClassLoader.build().urls(urls).parent(XmlSerializer.class.getClassLoader()).get(); final Class aClass; try { aClass = Class.forName(className, true, loader); diff --git a/plugins/google-app-engine/source/com/intellij/appengine/sdk/impl/AppEngineSdkUtil.java b/plugins/google-app-engine/source/com/intellij/appengine/sdk/impl/AppEngineSdkUtil.java index 15400345eae1..645c6f7ba2f8 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/sdk/impl/AppEngineSdkUtil.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/sdk/impl/AppEngineSdkUtil.java @@ -98,7 +98,8 @@ public class AppEngineSdkUtil { public static Map> computeWhiteList(final File toolsApiJarFile) { try { final THashMap> map = new THashMap>(); - ClassLoader loader = new UrlClassLoader(Collections.singletonList(toolsApiJarFile.toURI().toURL()), AppEngineSdkUtil.class.getClassLoader()); + final ClassLoader loader = UrlClassLoader.build().urls(toolsApiJarFile.toURI().toURL()).parent( + AppEngineSdkUtil.class.getClassLoader()).get(); final Class whiteListClass = Class.forName("com.google.apphosting.runtime.security.WhiteList", true, loader); final Set classes = (Set) whiteListClass.getMethod("getWhiteList").invoke(null); for (String qualifiedName : classes) { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradlePositionManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradlePositionManager.java index d01a931cb5a2..771260eb84d8 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradlePositionManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradlePositionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -149,7 +149,7 @@ public class GradlePositionManager extends ScriptPositionManagerHelper { } } - return new UrlClassLoader(urls, null); + return UrlClassLoader.build().urls(urls).get(); } private class ScriptSourceMapCalculator implements CachedValueProvider> { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java index d74aa376831c..d08cd9535062 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -144,7 +144,7 @@ public class AntTasksProvider { private final Future> myFuture; public AntClassLoader(ArrayList urls) { - super(urls, null, false, false, true, false); + super(build().urls(urls).allowUnescaped().noPreload()); myFuture = ApplicationManager.getApplication().executeOnPooledThread(new Callable>() { @Override public Map call() throws Exception { diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java index 0b82c99e9241..9c3fe6914a73 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java @@ -80,7 +80,7 @@ public class JavaFxInjectPageLanguageIntention extends PsiElementBaseIntentionAc } } - return new UrlClassLoader(urls, null); + return UrlClassLoader.build().urls(urls).get(); } @Override diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/LoaderFactory.java b/plugins/ui-designer/src/com/intellij/uiDesigner/LoaderFactory.java index 66d349a79bd4..4b95eefa8976 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/LoaderFactory.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/LoaderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -55,7 +55,7 @@ public final class LoaderFactory { public static LoaderFactory getInstance(final Project project) { return ServiceManager.getService(project, LoaderFactory.class); } - + public LoaderFactory(final Project project) { myProject = project; myModule2ClassLoader = new ConcurrentWeakHashMap(); @@ -155,7 +155,7 @@ public final class LoaderFactory { private final String myModuleName; public DesignTimeClassLoader(final List urls, final ClassLoader parent, final String moduleName) { - super(urls, parent); + super(build().urls(urls).parent(parent)); myModuleName = moduleName; }