View Javadoc
1   package org.codehaus.plexus.compiler.javac;
2   
3   /**
4    * The MIT License
5    *
6    * Copyright (c) 2005, The Codehaus
7    *
8    * Permission is hereby granted, free of charge, to any person obtaining a copy of
9    * this software and associated documentation files (the "Software"), to deal in
10   * the Software without restriction, including without limitation the rights to
11   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12   * of the Software, and to permit persons to whom the Software is furnished to do
13   * so, subject to the following conditions:
14   *
15   * The above copyright notice and this permission notice shall be included in all
16   * copies or substantial portions of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24   * SOFTWARE.
25   */
26  
27  import org.codehaus.plexus.compiler.AbstractCompilerTest;
28  import org.codehaus.plexus.compiler.CompilerConfiguration;
29  import org.codehaus.plexus.util.StringUtils;
30  
31  import java.io.File;
32  import java.util.ArrayList;
33  import java.util.Arrays;
34  import java.util.Collection;
35  import java.util.LinkedHashMap;
36  import java.util.List;
37  import java.util.Map;
38  
39  /**
40   * @author <a href="mailto:jason@plexus.org">Jason van Zyl</a>
41   */
42  public abstract class AbstractJavacCompilerTest
43      extends AbstractCompilerTest
44  {
45      private static final String PS = File.pathSeparator;
46  
47      public void setUp()
48          throws Exception
49      {
50          super.setUp();
51          setCompilerDebug( true );
52          setCompilerDeprecationWarnings( true );
53  
54      }
55  
56      protected String getRoleHint()
57      {
58          return "javac";
59      }
60  
61      protected int expectedErrors()
62      {
63  
64          if (getJavaVersion().contains("9.0")){
65              // lots of new warnings about obsoletions for future releases
66              return 5;
67          }
68  
69          // javac output changed for misspelled modifiers starting in 1.6...they now generate 2 errors per occurrence, not one.
70          if ( "1.5".compareTo( getJavaVersion() ) < 0 )
71          {
72              return 4;
73          }
74          else
75          {
76              return 3;
77          }
78      }
79  
80      protected int expectedWarnings()
81      {
82          if (getJavaVersion().contains("9.0")){
83              // lots of new warnings about obsoletions for future releases
84              return 8;
85          }
86  
87  
88          if (getJavaVersion().contains("1.8")){
89              // lots of new warnings about obsoletions for future releases
90              return 30;
91          }
92  
93          if ( "1.6".compareTo( getJavaVersion() ) < 0 )
94          {
95              // with 1.7 some warning with bootstrap class path not set in conjunction with -source 1.3
96              return 9;
97          }
98  
99          return 2;
100     }
101 
102     @Override
103     public String getTargetVersion()
104     {
105         if (getJavaVersion().contains("9.0")){
106             return "1.7";
107         }
108         return super.getTargetVersion();
109     }
110 
111     @Override
112     public String getSourceVersion()
113     {
114         if (getJavaVersion().contains("9.0")){
115             return "1.7";
116         }
117         return super.getTargetVersion();
118     }
119 
120     protected Collection<String> expectedOutputFiles()
121     {
122         if (getJavaVersion().contains("9.0")){
123             return Arrays.asList( new String[]{ "org/codehaus/foo/Deprecation.class", "org/codehaus/foo/ExternalDeps.class",
124                 "org/codehaus/foo/Person.class"} );
125         }
126         return Arrays.asList( new String[]{ "org/codehaus/foo/Deprecation.class", "org/codehaus/foo/ExternalDeps.class",
127             "org/codehaus/foo/Person.class", "org/codehaus/foo/ReservedWord.class" } );
128     }
129 
130     public void internalTest( CompilerConfiguration compilerConfiguration, List<String> expectedArguments )
131     {
132         String[] actualArguments = JavacCompiler.buildCompilerArguments( compilerConfiguration, new String[0] );
133 
134         assertEquals( "The expected and actual argument list sizes differ.", expectedArguments.size(),
135                       actualArguments.length );
136 
137         for ( int i = 0; i < actualArguments.length; i++ )
138         {
139             assertEquals( "Unexpected argument", expectedArguments.get( i ), actualArguments[i] );
140         }
141     }
142 
143     public void testBuildCompilerArgs13()
144     {
145         List<String> expectedArguments = new ArrayList<String>();
146 
147         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
148 
149         compilerConfiguration.setCompilerVersion( "1.3" );
150 
151         populateArguments( compilerConfiguration, expectedArguments, true, true, false );
152 
153         internalTest( compilerConfiguration, expectedArguments );
154     }
155 
156     public void testBuildCompilerArgs14()
157     {
158         List<String> expectedArguments = new ArrayList<String>();
159 
160         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
161 
162         compilerConfiguration.setCompilerVersion( "1.4" );
163 
164         populateArguments( compilerConfiguration, expectedArguments, false, false, false );
165 
166         internalTest( compilerConfiguration, expectedArguments );
167     }
168 
169     public void testBuildCompilerArgs15()
170     {
171         List<String> expectedArguments = new ArrayList<String>();
172 
173         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
174 
175         compilerConfiguration.setCompilerVersion( "1.5" );
176 
177         populateArguments( compilerConfiguration, expectedArguments, false, false, false );
178 
179         internalTest( compilerConfiguration, expectedArguments );
180     }
181 
182     public void testBuildCompilerArgs18()
183     {
184         List<String> expectedArguments = new ArrayList<String>();
185 
186         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
187 
188         compilerConfiguration.setCompilerVersion( "1.8" );
189 
190         populateArguments( compilerConfiguration, expectedArguments, false, false, true );
191 
192         internalTest( compilerConfiguration, expectedArguments );
193     }
194 
195     public void testBuildCompilerArgsUnspecifiedVersion()
196     {
197         List<String> expectedArguments = new ArrayList<String>();
198 
199         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
200 
201         populateArguments( compilerConfiguration, expectedArguments, false, false, false );
202 
203         internalTest( compilerConfiguration, expectedArguments );
204     }
205 
206     public void testBuildCompilerDebugLevel()
207     {
208         List<String> expectedArguments = new ArrayList<String>();
209 
210         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
211 
212         compilerConfiguration.setDebug( true );
213 
214         compilerConfiguration.setDebugLevel( "none" );
215 
216         populateArguments( compilerConfiguration, expectedArguments, false, false, false );
217 
218         internalTest( compilerConfiguration, expectedArguments );
219     }
220 
221     // PLXCOMP-190
222     public void testJRuntimeArguments()
223     {
224         List<String> expectedArguments = new ArrayList<String>();
225 
226         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
227 
228         // outputLocation
229         compilerConfiguration.setOutputLocation( "/output" );
230         expectedArguments.add( "-d" );
231         expectedArguments.add( new File( "/output" ).getAbsolutePath() );
232 
233         // targetVersion
234         compilerConfiguration.setTargetVersion( "1.3" );
235         expectedArguments.add( "-target" );
236         expectedArguments.add( "1.3" );
237 
238         // sourceVersion
239         compilerConfiguration.setSourceVersion( "1.3" );
240         expectedArguments.add( "-source" );
241         expectedArguments.add( "1.3" );
242 
243         // customCompilerArguments
244         Map<String, String> customCompilerArguments = new LinkedHashMap<String, String>();
245         customCompilerArguments.put( "-J-Duser.language=en_us", null );
246         compilerConfiguration.setCustomCompilerArgumentsAsMap( customCompilerArguments );
247         // don't expect this argument!!
248 
249         internalTest( compilerConfiguration, expectedArguments );
250     }
251 
252     public void testModulePath() throws Exception
253     {
254         List<String> expectedArguments = new ArrayList<String>();
255 
256         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
257 
258         // outputLocation
259         compilerConfiguration.setOutputLocation( "/output" );
260         expectedArguments.add( "-d" );
261         expectedArguments.add( new File( "/output" ).getAbsolutePath() );
262 
263         // failOnWarning
264         compilerConfiguration.setModulepathEntries( Arrays.asList( "/repo/a/b/1.0/b-1.0.jar",
265                                                                    "/repo/c/d/1.0/d-1.0.jar" ) );
266         expectedArguments.add( "--module-path" );
267         expectedArguments.add( "/repo/a/b/1.0/b-1.0.jar" + File.pathSeparator + 
268                                "/repo/c/d/1.0/d-1.0.jar" + File.pathSeparator );
269 
270         // default source + target
271         expectedArguments.add( "-target" );
272         expectedArguments.add( "1.1" );
273         expectedArguments.add( "-source" );
274         expectedArguments.add( "1.3" );
275 
276         internalTest( compilerConfiguration, expectedArguments );
277     }
278 
279     public void testModuleVersion()
280     {
281         List<String> expectedArguments = new ArrayList<String>();
282 
283         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
284 
285         // outputLocation
286         compilerConfiguration.setOutputLocation( "/output" );
287         expectedArguments.add( "-d" );
288         expectedArguments.add( new File( "/output" ).getAbsolutePath() );
289 
290         // default source + target
291         expectedArguments.add( "-target" );
292         expectedArguments.add( "1.1" );
293         expectedArguments.add( "-source" );
294         expectedArguments.add( "1.3" );
295 
296         // module version
297         compilerConfiguration.setModuleVersion( "1.2.0-SNAPSHOT" );
298         expectedArguments.add( "--module-version" );
299         expectedArguments.add( "1.2.0-SNAPSHOT" );
300 
301         internalTest( compilerConfiguration, expectedArguments );
302     }
303 
304     public void testReleaseVersion()
305     {
306         List<String> expectedArguments = new ArrayList<String>();
307 
308         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
309 
310         // outputLocation
311         compilerConfiguration.setOutputLocation( "/output" );
312         expectedArguments.add( "-d" );
313         expectedArguments.add( new File( "/output" ).getAbsolutePath() );
314 
315         // releaseVersion
316         compilerConfiguration.setReleaseVersion( "6" );
317         expectedArguments.add( "--release" );
318         expectedArguments.add( "6" );
319         
320         internalTest( compilerConfiguration, expectedArguments );
321     }
322 
323     public void testFailOnWarning()
324     {
325         List<String> expectedArguments = new ArrayList<String>();
326 
327         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
328 
329         // outputLocation
330         compilerConfiguration.setOutputLocation( "/output" );
331         expectedArguments.add( "-d" );
332         expectedArguments.add( new File( "/output" ).getAbsolutePath() );
333 
334         // failOnWarning
335         compilerConfiguration.setFailOnWarning( true );
336         expectedArguments.add( "-Werror" );
337         
338         // default source + target
339         expectedArguments.add( "-target" );
340         expectedArguments.add( "1.1" );
341         expectedArguments.add( "-source" );
342         expectedArguments.add( "1.3" );
343         
344         internalTest( compilerConfiguration, expectedArguments );
345     }
346 
347     public void testMultipleAddExports()
348     {
349         List<String> expectedArguments = new ArrayList<String>();
350 
351         CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
352 
353         // outputLocation
354         compilerConfiguration.setOutputLocation( "/output" );
355         expectedArguments.add( "-d" );
356         expectedArguments.add( new File( "/output" ).getAbsolutePath() );
357 
358         // default source + target
359         expectedArguments.add( "-target" );
360         expectedArguments.add( "1.1" );
361         expectedArguments.add( "-source" );
362         expectedArguments.add( "1.3" );
363 
364         // add multiple --add-exports
365         compilerConfiguration.addCompilerCustomArgument( "--add-exports", "FROM-MOD/package1=OTHER-MOD" );
366         expectedArguments.add( "--add-exports" );
367         expectedArguments.add( "FROM-MOD/package1=OTHER-MOD" );
368         compilerConfiguration.addCompilerCustomArgument( "--add-exports", "FROM-MOD/package2=OTHER-MOD" );
369         expectedArguments.add( "--add-exports" );
370         expectedArguments.add( "FROM-MOD/package2=OTHER-MOD" );
371         
372         internalTest( compilerConfiguration, expectedArguments );
373     }
374 
375     /* This test fails on Java 1.4. The multiple parameters of the same source file cause an error, as it is interpreted as a DuplicateClass
376      * Setting the size of the array to 3 is fine, but does not exactly test what it is supposed to - disabling the test for now
377     public void testCommandLineTooLongWhenForking()
378         throws Exception
379     {
380         JavacCompiler compiler = (JavacCompiler) lookup( org.codehaus.plexus.compiler.Compiler.ROLE, getRoleHint() );
381 
382         File destDir = new File( "target/test-classes-cmd" );
383         destDir.mkdirs();
384 
385         // fill the cmd line arguments, 300 is enough to make it break
386         String[] args = new String[400];
387         args[0] = "-d";
388         args[1] = destDir.getAbsolutePath();
389         for ( int i = 2; i < args.length; i++ )
390         {
391             args[i] = "org/codehaus/foo/Person.java";
392         }
393 
394         CompilerConfiguration config = new CompilerConfiguration();
395         config.setWorkingDirectory( new File( getBasedir() + "/src/test-input/src/main" ) );
396         config.setFork( true );
397 
398         List messages = compiler.compileOutOfProcess( config, "javac", args );
399 
400         assertEquals( "There were errors launching the external compiler: " + messages, 0, messages.size() );
401     }
402     */
403 
404     private void populateArguments( CompilerConfiguration compilerConfiguration, List<String> expectedArguments,
405                                     boolean suppressSourceVersion, boolean suppressEncoding, boolean parameters )
406     {
407         // outputLocation
408 
409         compilerConfiguration.setOutputLocation( "/output" );
410 
411         expectedArguments.add( "-d" );
412 
413         expectedArguments.add( new File( "/output" ).getAbsolutePath() );
414 
415         // classpathEntires
416 
417         List<String> classpathEntries = new ArrayList<String>();
418 
419         classpathEntries.add( "/myjar1.jar" );
420 
421         classpathEntries.add( "/myjar2.jar" );
422 
423         compilerConfiguration.setClasspathEntries( classpathEntries );
424 
425         expectedArguments.add( "-classpath" );
426 
427         expectedArguments.add( "/myjar1.jar" + PS + "/myjar2.jar" + PS );
428 
429         // sourceRoots
430 
431         List<String> compileSourceRoots = new ArrayList<String>();
432 
433         compileSourceRoots.add( "/src/main/one" );
434 
435         compileSourceRoots.add( "/src/main/two" );
436 
437         compilerConfiguration.setSourceLocations( compileSourceRoots );
438 
439         expectedArguments.add( "-sourcepath" );
440 
441         expectedArguments.add( "/src/main/one" + PS + "/src/main/two" + PS );
442 
443         // debug
444 
445         compilerConfiguration.setDebug( true );
446 
447         if ( StringUtils.isNotEmpty( compilerConfiguration.getDebugLevel() ) )
448         {
449             expectedArguments.add( "-g:" + compilerConfiguration.getDebugLevel() );
450         }
451         else
452         {
453             expectedArguments.add( "-g" );
454         }
455 
456         // parameters
457 
458         compilerConfiguration.setParameters( true );
459 
460         if (parameters)
461         {
462             expectedArguments.add( "-parameters" );
463         }
464         
465         // showDeprecation
466 
467         compilerConfiguration.setShowDeprecation( true );
468 
469         expectedArguments.add( "-deprecation" );
470 
471         // targetVersion
472 
473         compilerConfiguration.setTargetVersion( "1.3" );
474 
475         expectedArguments.add( "-target" );
476 
477         expectedArguments.add( "1.3" );
478 
479         // sourceVersion
480 
481         compilerConfiguration.setSourceVersion( "1.3" );
482 
483         if ( !suppressSourceVersion )
484         {
485             expectedArguments.add( "-source" );
486 
487             expectedArguments.add( "1.3" );
488         }
489 
490         // sourceEncoding
491 
492         compilerConfiguration.setSourceEncoding( "iso-8859-1" );
493 
494         if ( !suppressEncoding )
495         {
496             expectedArguments.add( "-encoding" );
497 
498             expectedArguments.add( "iso-8859-1" );
499         }
500 
501         // customerCompilerArguments
502 
503         Map<String, String> customerCompilerArguments = new LinkedHashMap<String, String>();
504 
505         customerCompilerArguments.put( "arg1", null );
506 
507         customerCompilerArguments.put( "foo", "bar" );
508 
509         compilerConfiguration.setCustomCompilerArgumentsAsMap( customerCompilerArguments );
510 
511         expectedArguments.add( "arg1" );
512 
513         expectedArguments.add( "foo" );
514 
515         expectedArguments.add( "bar" );
516     }
517 }