[vfs] dropping the obsolete JAR copying concept to make things simpler

GitOrigin-RevId: 2e7f2d0c3c04b5ed350eb15d0e21cf072f9c9a77
This commit is contained in:
Roman Shevchenko
2024-07-09 15:58:13 +02:00
committed by intellij-monorepo-bot
parent e2c160bd72
commit 474192eaad
10 changed files with 51 additions and 125 deletions

View File

@@ -2973,8 +2973,6 @@ c:com.intellij.openapi.vfs.InvalidVirtualFileAccessException
- java.lang.RuntimeException
- <init>(com.intellij.openapi.vfs.VirtualFile):V
- <init>(java.lang.String):V
com.intellij.openapi.vfs.JarCopyingFileSystem
- a:setNoCopyJarForPath(java.lang.String):V
com.intellij.openapi.vfs.LocalFileProvider
com.intellij.openapi.vfs.NonPhysicalFileSystem
f:com.intellij.openapi.vfs.PersistentFSConstants

View File

@@ -1,8 +0,0 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vfs;
import org.jetbrains.annotations.NotNull;
public interface JarCopyingFileSystem {
void setNoCopyJarForPath(@NotNull String pathInJar);
}

View File

@@ -2295,7 +2295,6 @@ c:com.intellij.openapi.vcs.UrlFilePath
- p:getPath(com.intellij.openapi.vfs.VirtualFile):java.lang.String
a:com.intellij.openapi.vfs.JarFileSystem
- com.intellij.openapi.vfs.newvfs.ArchiveFileSystem
- com.intellij.openapi.vfs.JarCopyingFileSystem
- com.intellij.openapi.vfs.VirtualFilePointerCapableFileSystem
- sf:JAR_SEPARATOR:java.lang.String
- sf:PROTOCOL:java.lang.String
@@ -2306,6 +2305,7 @@ a:com.intellij.openapi.vfs.JarFileSystem
- getJarRootForLocalFile(com.intellij.openapi.vfs.VirtualFile):com.intellij.openapi.vfs.VirtualFile
- getLocalVirtualFileFor(com.intellij.openapi.vfs.VirtualFile):com.intellij.openapi.vfs.VirtualFile
- getVirtualFileForJar(com.intellij.openapi.vfs.VirtualFile):com.intellij.openapi.vfs.VirtualFile
- setNoCopyJarForPath(java.lang.String):V
com.intellij.openapi.vfs.LargeFileWriteRequestor
com.intellij.openapi.vfs.SafeWriteRequestor
- s:shouldUseSafeWrite(java.lang.Object):Z

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.vfs;
import com.intellij.openapi.vfs.newvfs.ArchiveFileSystem;
@@ -6,7 +6,7 @@ import com.intellij.util.io.URLUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class JarFileSystem extends ArchiveFileSystem implements JarCopyingFileSystem, VirtualFilePointerCapableFileSystem {
public abstract class JarFileSystem extends ArchiveFileSystem implements VirtualFilePointerCapableFileSystem {
public static final String PROTOCOL = StandardFileSystems.JAR_PROTOCOL;
public static final String PROTOCOL_PREFIX = StandardFileSystems.JAR_PROTOCOL_PREFIX;
public static final String JAR_SEPARATOR = URLUtil.JAR_SEPARATOR;
@@ -38,5 +38,9 @@ public abstract class JarFileSystem extends ArchiveFileSystem implements JarCopy
}
return findFileByPath(path);
}
/** @deprecated no-op; stop using */
@Deprecated(forRemoval = true)
public void setNoCopyJarForPath(@SuppressWarnings("unused") @NotNull String pathInJar) { }
//</editor-fold>
}

View File

@@ -18160,7 +18160,7 @@ c:com.intellij.openapi.vfs.impl.jar.JarFileSystemImpl
- findFileByPath(java.lang.String):com.intellij.openapi.vfs.VirtualFile
- findFileByPathIfCached(java.lang.String):com.intellij.openapi.vfs.VirtualFile
- getArchiveCrcHashes(com.intellij.openapi.vfs.VirtualFile):java.util.Map
- p:getHandler(com.intellij.openapi.vfs.VirtualFile):com.intellij.openapi.vfs.impl.ArchiveHandler
- p:getHandler(com.intellij.openapi.vfs.VirtualFile):com.intellij.openapi.vfs.impl.ZipHandlerBase
- getMirroredFile(com.intellij.openapi.vfs.VirtualFile):java.io.File
- getProtocol():java.lang.String
- isMakeCopyOfJar(java.io.File):Z
@@ -18168,7 +18168,6 @@ c:com.intellij.openapi.vfs.impl.jar.JarFileSystemImpl
- p:normalize(java.lang.String):java.lang.String
- refresh(Z):V
- refreshAndFindFileByPath(java.lang.String):com.intellij.openapi.vfs.VirtualFile
- setNoCopyJarForPath(java.lang.String):V
f:com.intellij.openapi.vfs.impl.jar.TimedZipHandler
- com.intellij.openapi.vfs.impl.ZipHandlerBase
- <init>(java.lang.String):V

View File

@@ -1,67 +1,25 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.vfs.impl.jar;
import com.intellij.concurrency.ConcurrentCollectionFactory;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.IntegrityCheckCapableFileSystem;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.impl.ArchiveHandler;
import com.intellij.openapi.vfs.impl.ZipHandler;
import com.intellij.openapi.vfs.impl.ZipHandlerBase;
import com.intellij.openapi.vfs.newvfs.VfsImplUtil;
import com.intellij.util.containers.HashingStrategy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Map;
import java.util.Set;
public class JarFileSystemImpl extends JarFileSystem implements IntegrityCheckCapableFileSystem {
private final Set<String> myNoCopyJarPaths;
private final Path myNoCopyJarDir;
public JarFileSystemImpl() {
if (!SystemInfoRt.isWindows) {
myNoCopyJarPaths = null;
}
else if (SystemInfoRt.isFileSystemCaseSensitive) {
myNoCopyJarPaths = ConcurrentCollectionFactory.createConcurrentSet();
}
else {
myNoCopyJarPaths = ConcurrentCollectionFactory.createConcurrentSet(HashingStrategy.caseInsensitive());
}
// to prevent platform .jar files from copying
myNoCopyJarDir = Path.of(PathManager.getHomePath());
}
@Override
public void setNoCopyJarForPath(@NotNull String pathInJar) {
if (myNoCopyJarPaths == null) return;
int index = pathInJar.indexOf(JAR_SEPARATOR);
if (index > 0) pathInJar = pathInJar.substring(0, index);
myNoCopyJarPaths.add(new File(pathInJar).getPath());
}
public @Nullable File getMirroredFile(@NotNull VirtualFile file) {
return new File(file.getPath());
}
public boolean isMakeCopyOfJar(@NotNull File originalJar) {
return !(myNoCopyJarPaths == null ||
myNoCopyJarPaths.contains(originalJar.getPath()) ||
originalJar.toPath().startsWith(myNoCopyJarDir));
}
@Override
public @NotNull String getProtocol() {
return PROTOCOL;
@@ -95,8 +53,8 @@ public class JarFileSystemImpl extends JarFileSystem implements IntegrityCheckCa
}
@Override
protected @NotNull ArchiveHandler getHandler(@NotNull VirtualFile entryFile) {
return VfsImplUtil.getHandler(this, entryFile, myNoCopyJarPaths == null ? ZipHandler::new : TimedZipHandler::new);
protected @NotNull ZipHandlerBase getHandler(@NotNull VirtualFile entryFile) {
return VfsImplUtil.getHandler(this, entryFile, SystemInfo.isWindows ? TimedZipHandler::new : ZipHandler::new);
}
@TestOnly
@@ -137,7 +95,20 @@ public class JarFileSystemImpl extends JarFileSystem implements IntegrityCheckCa
@Override
public @NotNull Map<String, Long> getArchiveCrcHashes(@NotNull VirtualFile file) throws IOException {
ArchiveHandler handler = getHandler(file);
return ((ZipHandlerBase)handler).getArchiveCrcHashes();
return getHandler(file).getArchiveCrcHashes();
}
//<editor-fold desc="Deprecated stuff.">
/** @deprecated pointless; inline or avoid */
@Deprecated(forRemoval = true)
public @Nullable File getMirroredFile(@NotNull VirtualFile file) {
return new File(file.getPath());
}
/** @deprecated no-op; stop using */
@Deprecated(forRemoval = true)
public boolean isMakeCopyOfJar(@SuppressWarnings("unused") @NotNull File originalJar) {
return false;
}
//</editor-fold>
}

View File

@@ -2,7 +2,6 @@
package com.intellij.openapi.vfs.impl.jar;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.impl.ZipHandlerBase;
import com.intellij.util.concurrency.AppExecutorUtil;
import com.intellij.util.io.ResourceHandle;
@@ -48,7 +47,7 @@ public final class TimedZipHandler extends ZipHandlerBase {
public TimedZipHandler(@NotNull String path) {
super(path);
myHandle = new ZipResourceHandle(((JarFileSystemImpl)JarFileSystem.getInstance()).isMakeCopyOfJar(getFile()) ? RETENTION_MS : 5L * 60 * 1000);
myHandle = new ZipResourceHandle();
}
@Override
@@ -69,16 +68,11 @@ public final class TimedZipHandler extends ZipHandlerBase {
}
private final class ZipResourceHandle extends ResourceHandle<ZipFile> {
private final long myRetentionTime;
private ZipFile myFile;
private long myFileStamp;
private final ReentrantLock myLock = new ReentrantLock();
private ScheduledFuture<?> myInvalidationRequest;
private ZipResourceHandle(long retentionTime) {
myRetentionTime = retentionTime;
}
private void attach() throws IOException {
synchronized (ourLRUCache) {
ourLRUCache.remove(TimedZipHandler.this);
@@ -110,7 +104,7 @@ public final class TimedZipHandler extends ZipHandlerBase {
ScheduledFuture<?> invalidationRequest;
try {
myInvalidationRequest = invalidationRequest =
ourScheduledExecutorService.schedule(() -> { invalidateZipReference(null); }, myRetentionTime, TimeUnit.MILLISECONDS);
ourScheduledExecutorService.schedule(() -> { invalidateZipReference(null); }, RETENTION_MS, TimeUnit.MILLISECONDS);
}
finally {
myLock.unlock();

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.vfs.local;
import com.intellij.ide.plugins.DynamicPluginsTestUtil;
@@ -472,7 +472,7 @@ public class JarFileSystemTest extends BareTestFixtureTestCase {
}
@Override
protected @NotNull ArchiveHandler getHandler(@NotNull VirtualFile entryFile) {
protected @NotNull ZipHandlerBase getHandler(@NotNull VirtualFile entryFile) {
return VfsImplUtil.getHandler(this, entryFile, path -> new ZipHandler(path) {
@Override
protected @NotNull Map<String, EntryInfo> getEntriesMap() {

View File

@@ -429,7 +429,6 @@ public final class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
for (File child : files) {
String path = child.getAbsolutePath();
if (!path.contains("generics") && (path.endsWith(".jar") || path.endsWith(".zip"))) {
fs.setNoCopyJarForPath(path);
VirtualFile vFile = fs.refreshAndFindFileByPath(path + JarFileSystem.JAR_SEPARATOR);
if (vFile != null) {
sdkModificator.addRoot(vFile, OrderRootType.SOURCES);
@@ -474,7 +473,6 @@ public final class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
if (jarFile.exists()) {
JarFileSystem jarFileSystem = JarFileSystem.getInstance();
String path = jarFile.getAbsolutePath();
jarFileSystem.setNoCopyJarForPath(path);
VirtualFile vFile = jarFileSystem.refreshAndFindFileByPath(path + JarFileSystem.JAR_SEPARATOR);
if (vFile != null) {
sdkModificator.addRoot(vFile, OrderRootType.SOURCES);

View File

@@ -1,8 +1,7 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.uiDesigner;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.Service;
import com.intellij.openapi.module.Module;
@@ -11,13 +10,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.roots.OrderEnumerator;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.impl.jar.JarFileSystemImpl;
import com.intellij.uiDesigner.core.Spacer;
import com.intellij.util.SlowOperations;
import com.intellij.util.containers.CollectionFactory;
import com.intellij.util.lang.UrlClassLoader;
import com.intellij.util.messages.MessageBusConnection;
@@ -27,7 +21,6 @@ import javax.swing.*;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentMap;
@@ -35,10 +28,9 @@ import java.util.concurrent.ConcurrentMap;
@Service(Service.Level.PROJECT)
public final class LoaderFactory implements Disposable {
private final Project myProject;
private final ConcurrentMap<Module, ClassLoader> myModule2ClassLoader;
private ClassLoader myProjectClassLoader = null;
private final MessageBusConnection myConnection;
private ClassLoader myProjectClassLoader = null;
public static LoaderFactory getInstance(final Project project) {
return project.getService(LoaderFactory.class);
@@ -63,66 +55,45 @@ public final class LoaderFactory implements Disposable {
}
public @NotNull ClassLoader getLoader(@NotNull VirtualFile formFile) {
final Module module = ModuleUtilCore.findModuleForFile(formFile, myProject);
if (module == null) {
return getClass().getClassLoader();
}
return getLoader(module);
var module = ModuleUtilCore.findModuleForFile(formFile, myProject);
return module != null ? getLoader(module) : getClass().getClassLoader();
}
public ClassLoader getLoader(@NotNull Module module) {
final ClassLoader cachedLoader = myModule2ClassLoader.get(module);
if (cachedLoader != null) {
return cachedLoader;
}
final String runClasspath = OrderEnumerator.orderEntries(module).recursively().getPathsList().getPathsString();
final ClassLoader classLoader = createClassLoader(runClasspath, module.getName());
var cachedLoader = myModule2ClassLoader.get(module);
if (cachedLoader != null) return cachedLoader;
var runClasspath = OrderEnumerator.orderEntries(module).recursively().getPathsList().getPathsString();
var classLoader = createClassLoader(runClasspath, module.getName());
myModule2ClassLoader.put(module, classLoader);
return classLoader;
}
public @NotNull ClassLoader getProjectClassLoader() {
if (myProjectClassLoader == null) {
final String runClasspath = OrderEnumerator.orderEntries(myProject).withoutSdk().getPathsList().getPathsString();
var runClasspath = OrderEnumerator.orderEntries(myProject).withoutSdk().getPathsList().getPathsString();
myProjectClassLoader = createClassLoader(runClasspath, "<project>");
}
return myProjectClassLoader;
}
private static ClassLoader createClassLoader(final String runClasspath, final String moduleName) {
List<Path> files = new ArrayList<>();
final VirtualFileManager manager = VirtualFileManager.getInstance();
final JarFileSystemImpl fileSystem = (JarFileSystemImpl)JarFileSystem.getInstance();
final StringTokenizer tokenizer = new StringTokenizer(runClasspath, File.pathSeparator);
while (tokenizer.hasMoreTokens()) {
final String s = tokenizer.nextToken();
try (AccessToken ignore = SlowOperations.knownIssue("IDEA-307701")) {
VirtualFile vFile = manager.findFileByUrl(VfsUtilCore.pathToUrl(s));
File realFile = fileSystem.getMirroredFile(vFile);
files.add(realFile == null ? new File(s).toPath() : realFile.toPath());
}
catch (Exception e) {
// ignore ?
}
private static ClassLoader createClassLoader(String runClasspath, String moduleName) {
var files = new ArrayList<Path>();
for (var tokenizer = new StringTokenizer(runClasspath, File.pathSeparator); tokenizer.hasMoreTokens(); ) {
files.add(Path.of(tokenizer.nextToken()));
}
files.add(PathManager.getJarForClass(Spacer.class));
return new DesignTimeClassLoader(files, LoaderFactory.class.getClassLoader(), moduleName);
}
public void clearClassLoaderCache() {
// clear classes with invalid classloader from UIManager cache
final UIDefaults uiDefaults = UIManager.getDefaults();
for (Iterator it = uiDefaults.keySet().iterator(); it.hasNext();) {
Object key = it.next();
Object value = uiDefaults.get(key);
var uiDefaults = UIManager.getDefaults();
for (var it = uiDefaults.keySet().iterator(); it.hasNext(); ) {
var key = it.next();
var value = uiDefaults.get(key);
if (value instanceof Class) {
ClassLoader loader = ((Class<?>)value).getClassLoader();
var loader = ((Class<?>)value).getClassLoader();
if (loader instanceof DesignTimeClassLoader) {
it.remove();
}
@@ -138,8 +109,7 @@ public final class LoaderFactory implements Disposable {
private final String myModuleName;
DesignTimeClassLoader(List<Path> files, ClassLoader parent, String moduleName) {
super(UrlClassLoader.build().files(files).allowLock(false).parent(parent), isParallelCapable);
super(build().files(files).allowLock(false).parent(parent), isParallelCapable);
myModuleName = moduleName;
}
@@ -148,4 +118,4 @@ public final class LoaderFactory implements Disposable {
return "DesignTimeClassLoader:" + myModuleName;
}
}
}
}