Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 141522 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java (-2 / +82 lines)
Lines 2914-2921 Link Here
2914
        + " -1.5 -g -preserveAllLocals"
2914
        + " -1.5 -g -preserveAllLocals"
2915
        + " -d \"" + OUTPUT_DIR + File.separator + "X.java\"",
2915
        + " -d \"" + OUTPUT_DIR + File.separator + "X.java\"",
2916
		"", 
2916
		"", 
2917
		"No .class file created for file X.class in ---OUTPUT_DIR_PLACEHOLDER---/X.java because of an IOException: The output directory is a file : ---OUTPUT_DIR_PLACEHOLDER---/X.java\n",
2917
		"No .class file created for file X.class in ---OUTPUT_DIR_PLACEHOLDER" +
2918
        true);
2918
			"---/X.java because of an IOException: Regular file " +
2919
			"---OUTPUT_DIR_PLACEHOLDER---/X.java cannot be used " +
2920
			"as output directory\n",
2921
		true);
2922
}
2923
// suggested by https://bugs.eclipse.org/bugs/show_bug.cgi?id=141522
2924
// only checking messages (the bug itself involves concurrent access to
2925
// the file system and a true test case would call for instrumented
2926
// code)
2927
public void test054(){
2928
	this.runConformTest(
2929
		new String[] {
2930
			"X.java",
2931
			"public class X {}",
2932
			"f", // create simple file f
2933
			""
2934
        },
2935
        "\"" + OUTPUT_DIR +  File.separator + "X.java\""
2936
        + " -1.5 -g -preserveAllLocals"
2937
        + " -d \"" + OUTPUT_DIR + "/f/out\"",
2938
		"", 
2939
		"No .class file created for file X.class in ---OUTPUT_DIR_PLACEHOLDER" +
2940
			"---/f/out because of an IOException: " +
2941
			"Could not create output directory ---OUTPUT_DIR_PLACEHOLDER---/f/out\n",
2942
		true);
2943
}
2944
// suggested by https://bugs.eclipse.org/bugs/show_bug.cgi?id=141522
2945
// only checking messages (the bug itself involves concurrent access to
2946
// the file system and a true test case would call for instrumented
2947
// code)
2948
// this test only works on appropriate file systems
2949
public void test055(){
2950
	if (File.separatorChar == '/') {
2951
	  	String tentativeOutputDirNameTail = 
2952
	      	File.separator + "out";
2953
	  	File outputDirectory = new File(OUTPUT_DIR + tentativeOutputDirNameTail);
2954
	  	outputDirectory.mkdirs();
2955
	  	outputDirectory.setReadOnly(); 
2956
	  	// read-only directories do not prevent file creation 
2957
	  	// on under-gifted file systems
2958
		this.runConformTest(
2959
			new String[] {
2960
				"p/X.java",
2961
				"package p;\n" +
2962
				"public class X {}",
2963
	        },
2964
	        "\"" + OUTPUT_DIR +  File.separator + "p/X.java\""
2965
	        + " -1.5 -g -preserveAllLocals"
2966
	        + " -d \"" + OUTPUT_DIR + "/out\"",
2967
			"", 
2968
			"No .class file created for file p/X.class in " +
2969
				"---OUTPUT_DIR_PLACEHOLDER---/out because of " +
2970
				"an IOException: Could not create subdirectory p into output directory " +
2971
				"---OUTPUT_DIR_PLACEHOLDER---/out\n",
2972
			false /* do not flush output directory */);
2973
	}
2974
}
2975
// suggested by https://bugs.eclipse.org/bugs/show_bug.cgi?id=141522
2976
// only checking messages (the bug itself involves concurrent access to
2977
// the file system and a true test case would call for instrumented
2978
// code)
2979
public void test056(){
2980
  	String tentativeOutputDirNameTail = 
2981
      	File.separator + "out";
2982
	this.runConformTest(
2983
		new String[] {
2984
			"p/X.java",
2985
			"package p;\n" +
2986
			"public class X {}",
2987
			"out/p", // create simple file out/p
2988
			""
2989
        },
2990
        "\"" + OUTPUT_DIR +  File.separator + "p/X.java\""
2991
        + " -1.5 -g -preserveAllLocals"
2992
        + " -d \"" + OUTPUT_DIR + tentativeOutputDirNameTail + "\"",
2993
		"", 
2994
		"No .class file created for file p/X.class in " +
2995
			"---OUTPUT_DIR_PLACEHOLDER---/out" + 
2996
			" because of an IOException: Regular file ---OUTPUT_DIR_PLACEHOLDER---" + 
2997
			"/out/p cannot be used as output directory\n",
2998
		true);
2919
}
2999
}
2920
public static Class testClass() {
3000
public static Class testClass() {
2921
	return BatchCompilerTest.class;
3001
	return BatchCompilerTest.class;
(-)compiler/org/eclipse/jdt/internal/compiler/messages.properties (-3 / +3 lines)
Lines 23-31 Link Here
23
compilation_internalError = Internal compiler error
23
compilation_internalError = Internal compiler error
24
24
25
### output
25
### output
26
output_isFile =  The output directory is a file : {0}
26
output_isFile =  Regular file {0} cannot be used as output directory
27
output_notValidAll =  The output directory {0} is not a valid directory name. All the directories cannot be created
27
output_notValidAll =  Could not create output directory {0}
28
output_notValid = The output directory ''{0}'' is not a valid directory name. The directory cannot be created
28
output_notValid = Could not create subdirectory {0} into output directory {1}
29
29
30
### problem
30
### problem
31
problem_noSourceInformation =
31
problem_noSourceInformation =
(-)compiler/org/eclipse/jdt/internal/compiler/ClassFile.java (-30 / +87 lines)
Lines 110-154 Link Here
110
		char fileSeparatorChar = File.separatorChar;
110
		char fileSeparatorChar = File.separatorChar;
111
		String fileSeparator = File.separator;
111
		String fileSeparator = File.separator;
112
		File f;
112
		File f;
113
		// First we ensure that the outputPath exists
114
		outputPath = outputPath.replace('/', fileSeparatorChar);
113
		outputPath = outputPath.replace('/', fileSeparatorChar);
115
		// To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
114
			// these could be optimized out if we normalized paths once and for
116
		if (outputPath.endsWith(fileSeparator)) {
115
			// all
117
			outputPath = outputPath.substring(0, outputPath.length() - 1);
116
		relativeFileName = relativeFileName.replace('/', fileSeparatorChar);
118
		}
117
		String outputDirPath, fileName;
119
		f = new File(outputPath);
118
		int separatorIndex = relativeFileName.lastIndexOf(fileSeparatorChar);
120
		if (f.exists()) {
119
		if (separatorIndex == -1) {
121
			if (!f.isDirectory()) {
120
			if (outputPath.endsWith(fileSeparator)) {
122
				final String message = Messages.bind(Messages.output_isFile, f.getAbsolutePath());
121
				outputDirPath = outputPath.substring(0, outputPath.length() - 1);
123
				throw new IOException(message);
122
				fileName = outputPath + relativeFileName;
123
			} else {
124
				outputDirPath = outputPath;
125
				fileName = outputPath + fileSeparator + relativeFileName;
124
			}
126
			}
125
		} else {
127
		} else {
126
			// we have to create that directory
128
			if (outputPath.endsWith(fileSeparator)) {
127
			if (!f.mkdirs()) {
129
				outputDirPath = outputPath + 
128
				final String message = Messages.bind(Messages.output_notValidAll, f.getAbsolutePath());
130
					relativeFileName.substring(0, separatorIndex);
129
				throw new IOException(message);
131
				fileName = outputPath + relativeFileName;
132
			} else {
133
				outputDirPath = outputPath + fileSeparator +
134
					relativeFileName.substring(0, separatorIndex);
135
				fileName = outputPath + fileSeparator + relativeFileName;
130
			}
136
			}
131
		}
137
		}
132
		StringBuffer outDir = new StringBuffer(outputPath);
138
		f = new File(outputDirPath);
133
		outDir.append(fileSeparator);
139
		f.mkdirs();
134
		StringTokenizer tokenizer =
140
		if (f.isDirectory()) {
135
			new StringTokenizer(relativeFileName, fileSeparator);
141
			return fileName;
136
		String token = tokenizer.nextToken();
142
		} else {
137
		while (tokenizer.hasMoreTokens()) {
143
			// the directory creation failed for some reason - retry using
138
			f = new File(outDir.append(token).append(fileSeparator).toString());
144
			// a slower algorithm so as to refine the diagnostic
145
			if (outputPath.endsWith(fileSeparator)) {
146
				outputPath = outputPath.substring(0, outputPath.length() - 1);
147
			}
148
			f = new File(outputPath);
149
			boolean checkFileType = false;
139
			if (f.exists()) {
150
			if (f.exists()) {
140
				// The outDir already exists, so we proceed the next entry
151
			  	checkFileType = true; // pre-existed
141
				// System.out.println("outDir: " + outDir + " already exists.");
142
			} else {
152
			} else {
143
				// Need to add the outDir
153
				// we have to create that directory
144
				if (!f.mkdir()) {
154
				if (!f.mkdirs()) {
145
					throw new IOException(Messages.bind(Messages.output_notValid, f.getName()));
155
				  	if (f.exists()) {
146
				}
156
				  	  	// someone else created f -- need to check its type
157
				  	  	checkFileType = true;
158
				  	} else {
159
				  	  	// no one could create f -- complain
160
	    				throw new IOException(Messages.bind(
161
	    					Messages.output_notValidAll, f.getAbsolutePath()));
162
				  	}
163
				}
164
			}
165
			if (checkFileType) {
166
			  	if (!f.isDirectory()) {
167
	    			throw new IOException(Messages.bind(
168
	    				Messages.output_isFile, f.getAbsolutePath()));
169
			  	}
170
			}
171
			StringBuffer outDir = new StringBuffer(outputPath);
172
			outDir.append(fileSeparator);
173
			StringTokenizer tokenizer =
174
				new StringTokenizer(relativeFileName, fileSeparator);
175
			String token = tokenizer.nextToken();
176
			while (tokenizer.hasMoreTokens()) {
177
				f = new File(outDir.append(token).append(fileSeparator).toString());
178
			  	checkFileType = false; // reset
179
				if (f.exists()) {
180
				  	checkFileType = true; // this is suboptimal, but it catches corner cases
181
				  						  // in which a regular file pre-exists
182
				} else {
183
				// we have to create that directory
184
	    			if (!f.mkdir()) {
185
	    			  	if (f.exists()) {
186
	    			  	  	// someone else created f -- need to check its type
187
	    			  	  	checkFileType = true;
188
	    			  	} else {
189
	    			  	  	// no one could create f -- complain
190
	        				throw new IOException(Messages.bind(
191
	        					Messages.output_notValid, 
192
	        						outDir.substring(outputPath.length() + 1, 
193
	        							outDir.length() - 1),
194
	        						outputPath));
195
	    			  	}
196
	    			}
197
				}
198
	    		if (checkFileType) {
199
	    		  	if (!f.isDirectory()) {
200
	        			throw new IOException(Messages.bind(
201
	        				Messages.output_isFile, f.getAbsolutePath()));
202
	    		  	}
203
	    		}
204
				token = tokenizer.nextToken();
147
			}
205
			}
148
			token = tokenizer.nextToken();
206
			// token contains the last one
207
			return outDir.append(token).toString();
149
		}
208
		}
150
		// token contains the last one
151
		return outDir.append(token).toString();
152
	}
209
	}
153
210
154
	/**
211
	/**

Return to bug 141522