View | Details | Raw Unified | Return to bug 260848 | Differences between
and this patch

Collapse All | Expand All

(-)model/org/eclipse/jdt/internal/core/JavaModelManager.java (+103 lines)
Lines 1126-1131 Link Here
1126
		}
1126
		}
1127
1127
1128
		public synchronized ClasspathChange resetResolvedClasspath() {
1128
		public synchronized ClasspathChange resetResolvedClasspath() {
1129
			// clear non-chaining jars cache
1130
			JavaModelManager.getJavaModelManager().resetNonChainingJarsCache();
1131
			
1129
			// null out resolved information
1132
			// null out resolved information
1130
			return setResolvedClasspath(null, null, null, null, this.rawTimeStamp);
1133
			return setResolvedClasspath(null, null, null, null, this.rawTimeStamp);
1131
		}
1134
		}
Lines 1336-1341 Link Here
1336
	private ThreadLocal zipFiles = new ThreadLocal();
1339
	private ThreadLocal zipFiles = new ThreadLocal();
1337
1340
1338
	private UserLibraryManager userLibraryManager;
1341
	private UserLibraryManager userLibraryManager;
1342
	
1343
	/*
1344
	 * List of IPath of jars that are known to not contain a chaining (through MANIFEST.MF) to another library
1345
	 */
1346
	private HashSet nonChainingJars;
1339
1347
1340
	/**
1348
	/**
1341
	 * Update the classpath variable cache
1349
	 * Update the classpath variable cache
Lines 1461-1466 Link Here
1461
	private JavaModelManager() {
1469
	private JavaModelManager() {
1462
		// singleton: prevent others from creating a new instance
1470
		// singleton: prevent others from creating a new instance
1463
		if (Platform.isRunning()) this.indexManager = new IndexManager();
1471
		if (Platform.isRunning()) this.indexManager = new IndexManager();
1472
		this.nonChainingJars = loadNonChainingJarsCache();
1464
	}
1473
	}
1465
1474
1466
	/**
1475
	/**
Lines 1470-1475 Link Here
1470
		options.put(JavaCore.COMPILER_PB_INVALID_IMPORT, JavaCore.ERROR);
1479
		options.put(JavaCore.COMPILER_PB_INVALID_IMPORT, JavaCore.ERROR);
1471
		options.put(JavaCore.COMPILER_PB_UNREACHABLE_CODE, JavaCore.ERROR);
1480
		options.put(JavaCore.COMPILER_PB_UNREACHABLE_CODE, JavaCore.ERROR);
1472
	}
1481
	}
1482
	
1483
	public void addNonChainingJar(IPath path) {
1484
		if (this.nonChainingJars == null)
1485
			return;
1486
		this.nonChainingJars.add(path);
1487
	}
1473
1488
1474
	/**
1489
	/**
1475
	 * Starts caching ZipFiles.
1490
	 * Starts caching ZipFiles.
Lines 2800-2805 Link Here
2800
		return JavaCore.COMPILER_PB_INVALID_IMPORT.equals(optionName)
2815
		return JavaCore.COMPILER_PB_INVALID_IMPORT.equals(optionName)
2801
				|| JavaCore.COMPILER_PB_UNREACHABLE_CODE.equals(optionName);
2816
				|| JavaCore.COMPILER_PB_UNREACHABLE_CODE.equals(optionName);
2802
	}
2817
	}
2818
	
2819
	public boolean isNonChainingJar(IPath path) {
2820
		return this.nonChainingJars != null && this.nonChainingJars.contains(path);
2821
	}
2803
2822
2804
	public void setClasspathBeingResolved(IJavaProject project, boolean classpathIsResolved) {
2823
	public void setClasspathBeingResolved(IJavaProject project, boolean classpathIsResolved) {
2805
	    if (classpathIsResolved) {
2824
	    if (classpathIsResolved) {
Lines 2808-2813 Link Here
2808
	        getClasspathBeingResolved().remove(project);
2827
	        getClasspathBeingResolved().remove(project);
2809
	    }
2828
	    }
2810
	}
2829
	}
2830
	
2831
	private HashSet loadNonChainingJarsCache() {
2832
		HashSet nonChainingJarsCache = new HashSet();
2833
		File nonChainingJarsFile = getNonChainingJarsFile();
2834
		DataInputStream in = null;
2835
		try {
2836
			in = new DataInputStream(new BufferedInputStream(new FileInputStream(nonChainingJarsFile)));
2837
			int size = in.readInt();
2838
			while (size-- > 0) {
2839
				String path = in.readUTF();
2840
				nonChainingJarsCache.add(Path.fromPortableString(path));
2841
			}
2842
		} catch (IOException e) {
2843
			if (nonChainingJarsFile.exists())
2844
				Util.log(e, "Unable to read non-chaining jar cache file"); //$NON-NLS-1$
2845
		} finally {
2846
			if (in != null) {
2847
				try {
2848
					in.close();
2849
				} catch (IOException e) {
2850
					// nothing we can do: ignore
2851
				}
2852
			}
2853
		}
2854
		return nonChainingJarsCache;
2855
	}
2856
2857
	private File getNonChainingJarsFile() {
2858
		return JavaCore.getPlugin().getStateLocation().append("nonChainingJarsCache").toFile(); //$NON-NLS-1$
2859
	}
2860
	
2861
	private HashSet getNonChainingJarsCache() throws CoreException {
2862
		if (this.nonChainingJars != null)
2863
			return this.nonChainingJars;
2864
		HashSet result = new HashSet();
2865
		IJavaProject[] projects = getJavaModel().getJavaProjects();
2866
		for (int i = 0, length = projects.length; i < length; i++) {
2867
			IJavaProject javaProject = projects[i];
2868
			IClasspathEntry[] classpath = ((JavaProject) javaProject).getResolvedClasspath();
2869
			for (int j = 0, length2 = classpath.length; j < length2; j++) {
2870
				IClasspathEntry entry = classpath[j];
2871
				IPath path;
2872
				if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY 
2873
					&& !result.contains(path = entry.getPath())
2874
					&& ClasspathEntry.resolvedChainedLibraries(path).length == 0) {
2875
						result.add(path);
2876
				}
2877
			}
2878
		}
2879
		return result;
2880
	}
2811
2881
2812
	public void loadVariablesAndContainers() throws CoreException {
2882
	public void loadVariablesAndContainers() throws CoreException {
2813
		// backward compatibility, consider persistent property
2883
		// backward compatibility, consider persistent property
Lines 3524-3529 Link Here
3524
	protected synchronized void resetJarTypeCache() {
3594
	protected synchronized void resetJarTypeCache() {
3525
		this.cache.resetJarTypeCache();
3595
		this.cache.resetJarTypeCache();
3526
	}
3596
	}
3597
	
3598
	public void resetNonChainingJarsCache() {
3599
		this.nonChainingJars = null;
3600
	}
3527
3601
3528
	/*
3602
	/*
3529
	 * Resets the temporary cache for newly created elements to null.
3603
	 * Resets the temporary cache for newly created elements to null.
Lines 3596-3601 Link Here
3596
		}
3670
		}
3597
	}
3671
	}
3598
3672
3673
	private void saveNonChainingJarsCache() throws CoreException {
3674
		File file = getNonChainingJarsFile();
3675
		DataOutputStream out = null;
3676
		try {
3677
			out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
3678
			HashSet nonChainingJarsCache = getNonChainingJarsCache();
3679
			out.writeInt(nonChainingJarsCache.size());
3680
			Iterator entries = nonChainingJarsCache.iterator();
3681
			while (entries.hasNext()) {
3682
				IPath path = (IPath) entries.next();
3683
				out.writeUTF(path.toPortableString());
3684
			}
3685
		} catch (IOException e) {
3686
			IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving non-chaining jar cache", e); //$NON-NLS-1$
3687
			throw new CoreException(status);
3688
		} finally {
3689
			if (out != null) {
3690
				try {
3691
					out.close();
3692
				} catch (IOException e) {
3693
					// nothing we can do: ignore
3694
				}
3695
			}
3696
		}
3697
	}
3698
	
3599
	private void saveVariablesAndContainers(ISaveContext context) throws CoreException {
3699
	private void saveVariablesAndContainers(ISaveContext context) throws CoreException {
3600
		File file = getVariableAndContainersFile();
3700
		File file = getVariableAndContainersFile();
3601
		DataOutputStream out = null;
3701
		DataOutputStream out = null;
Lines 3849-3854 Link Here
3849
3949
3850
		// save variable and container values on snapshot/full save
3950
		// save variable and container values on snapshot/full save
3851
		saveVariablesAndContainers(context);
3951
		saveVariablesAndContainers(context);
3952
		
3953
		// save non-chaining jar cache on snapshot/full save
3954
		saveNonChainingJarsCache();
3852
3955
3853
		if (VERBOSE)
3956
		if (VERBOSE)
3854
			traceVariableAndContainers("Saved", start); //$NON-NLS-1$
3957
			traceVariableAndContainers("Saved", start); //$NON-NLS-1$
(-)model/org/eclipse/jdt/internal/core/ClasspathEntry.java (-55 / +67 lines)
Lines 874-943 Link Here
874
		if (visited.contains( jarPath))
874
		if (visited.contains( jarPath))
875
			return;
875
			return;
876
		visited.add(jarPath);
876
		visited.add(jarPath);
877
		Object target = JavaModel.getTarget(jarPath, true/*check existence, otherwise the manifest cannot be read*/);
877
		JavaModelManager manager = JavaModelManager.getJavaModelManager();
878
		if (target instanceof IFile || target instanceof File) {
878
		if (manager.isNonChainingJar(jarPath))
879
			JavaModelManager manager = JavaModelManager.getJavaModelManager();
879
			return;
880
			ZipFile zip = null;
880
		List calledFileNames = getCalledFileNames(jarPath);
881
			BufferedReader reader = null;
881
		if (calledFileNames == null) {
882
			try {
882
			manager.addNonChainingJar(jarPath);
883
				zip = manager.getZipFile(jarPath);
883
		} else {
884
				ZipEntry manifest =	zip.getEntry("META-INF/MANIFEST.MF"); //$NON-NLS-1$
884
			Iterator calledFilesIterator = calledFileNames.iterator();
885
				if (manifest != null) { // non-null implies regular file
885
			IPath directoryPath = jarPath.removeLastSegments(1);
886
					reader = new BufferedReader(new InputStreamReader(zip.getInputStream(manifest)));
886
			while (calledFilesIterator.hasNext()) {
887
					ManifestAnalyzer analyzer = new ManifestAnalyzer();
887
				String calledFileName = (String) calledFilesIterator.next();
888
					boolean success = analyzer.analyzeManifestContents(reader);
888
				if (!directoryPath.isValidPath(calledFileName)) {
889
					List calledFileNames = analyzer.getCalledFileNames();
889
					if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
890
					if (!success || analyzer.getClasspathSectionsCount() == 1 && calledFileNames == null) {
890
						Util.verbose("Invalid Class-Path entry " + calledFileName + " in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
891
						if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
892
							Util.verbose("Invalid Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
893
						}
894
						return;
895
					} else if (analyzer.getClasspathSectionsCount() > 1) {
896
						if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
897
							Util.verbose("Multiple Class-Path headers in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
898
						}
899
						return;
900
					}
901
					if (calledFileNames != null) {
902
						Iterator calledFilesIterator = calledFileNames.iterator();
903
						IPath directoryPath = jarPath.removeLastSegments(1);
904
						while (calledFilesIterator.hasNext()) {
905
							String calledFileName = (String) calledFilesIterator.next();
906
							if (!directoryPath.isValidPath(calledFileName)) {
907
								if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
908
									Util.verbose("Invalid Class-Path entry " + calledFileName + " in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
909
								}
910
							} else {
911
								IPath calledJar = directoryPath.append(new Path(calledFileName));
912
								resolvedChainedLibraries(calledJar, visited, result);
913
								result.add(calledJar);
914
							}
915
						}
916
					}
891
					}
892
				} else {
893
					IPath calledJar = directoryPath.append(new Path(calledFileName));
894
					resolvedChainedLibraries(calledJar, visited, result);
895
					result.add(calledJar);
917
				}
896
				}
918
			} catch (CoreException e) {
897
			}
919
				// not a zip file
898
		}
899
	}
900
901
	private static List getCalledFileNames(IPath jarPath) {
902
		Object target = JavaModel.getTarget(jarPath, true/*check existence, otherwise the manifest cannot be read*/);
903
		if (!(target instanceof IFile || target instanceof File))
904
			return null;
905
		JavaModelManager manager = JavaModelManager.getJavaModelManager();
906
		ZipFile zip = null;
907
		BufferedReader reader = null;
908
		List calledFileNames = null;
909
		try {
910
			zip = manager.getZipFile(jarPath);
911
			ZipEntry manifest =	zip.getEntry("META-INF/MANIFEST.MF"); //$NON-NLS-1$
912
			if (manifest == null) 
913
				return null;
914
			// non-null implies regular file
915
			reader = new BufferedReader(new InputStreamReader(zip.getInputStream(manifest)));
916
			ManifestAnalyzer analyzer = new ManifestAnalyzer();
917
			boolean success = analyzer.analyzeManifestContents(reader);
918
			calledFileNames = analyzer.getCalledFileNames();
919
			if (!success || analyzer.getClasspathSectionsCount() == 1 && calledFileNames == null) {
920
				if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
920
				if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
921
					Util.verbose("Could not read Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
921
					Util.verbose("Invalid Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
922
					e.printStackTrace();
923
				}
922
				}
924
			} catch (IOException e) {
923
				return null;
925
				// not a zip file
924
			} else if (analyzer.getClasspathSectionsCount() > 1) {
926
				if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
925
				if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
927
					Util.verbose("Could not read Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
926
					Util.verbose("Multiple Class-Path headers in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
928
					e.printStackTrace();
929
				}
927
				}
930
			} finally {
928
				return null;
931
				manager.closeZipFile(zip);
929
			}
932
				if (reader != null) {
930
		} catch (CoreException e) {
933
					try {
931
			// not a zip file
934
						reader.close();
932
			if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
935
					} catch (IOException e) {
933
				Util.verbose("Could not read Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
936
						// best effort
934
				e.printStackTrace();
937
					}
935
			}
936
		} catch (IOException e) {
937
			// not a zip file
938
			if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
939
				Util.verbose("Could not read Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
940
				e.printStackTrace();
941
			}
942
		} finally {
943
			manager.closeZipFile(zip);
944
			if (reader != null) {
945
				try {
946
					reader.close();
947
				} catch (IOException e) {
948
					// best effort
938
				}
949
				}
939
			}
950
			}
940
		}
951
		}
952
		return calledFileNames;
941
	}
953
	}
942
	
954
	
943
	/*
955
	/*

Return to bug 260848