1 package org.apache.maven.plugins.jar;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.archiver.MavenArchiveConfiguration;
23 import org.apache.maven.archiver.MavenArchiver;
24 import org.apache.maven.execution.MavenSession;
25 import org.apache.maven.plugin.AbstractMojo;
26 import org.apache.maven.plugin.MojoExecutionException;
27 import org.apache.maven.plugins.annotations.Component;
28 import org.apache.maven.plugins.annotations.Parameter;
29 import org.apache.maven.project.MavenProject;
30 import org.apache.maven.project.MavenProjectHelper;
31 import org.apache.maven.shared.model.fileset.FileSet;
32 import org.apache.maven.shared.model.fileset.util.FileSetManager;
33 import org.codehaus.plexus.archiver.Archiver;
34 import org.codehaus.plexus.archiver.jar.JarArchiver;
35
36 import java.io.File;
37 import java.util.Arrays;
38 import java.util.Map;
39
40
41
42
43
44
45
46 public abstract class AbstractJarMojo
47 extends AbstractMojo
48 {
49
50 private static final String[] DEFAULT_EXCLUDES = new String[] { "**/package.html" };
51
52 private static final String[] DEFAULT_INCLUDES = new String[] { "**/**" };
53
54 private static final String MODULE_DESCRIPTOR_FILE_NAME = "module-info.class";
55
56
57
58
59
60 @Parameter
61 private String[] includes;
62
63
64
65
66
67 @Parameter
68 private String[] excludes;
69
70
71
72
73 @Parameter( defaultValue = "${project.build.directory}", required = true )
74 private File outputDirectory;
75
76
77
78
79 @Parameter( defaultValue = "${project.build.finalName}", readonly = true )
80 private String finalName;
81
82
83
84
85 @Component
86 private Map<String, Archiver> archivers;
87
88
89
90
91 @Parameter( defaultValue = "${project}", readonly = true, required = true )
92 private MavenProject project;
93
94
95
96
97 @Parameter( defaultValue = "${session}", readonly = true, required = true )
98 private MavenSession session;
99
100
101
102
103
104 @Parameter
105 private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
106
107
108
109
110
111
112
113
114 @Parameter( property = "jar.useDefaultManifestFile", defaultValue = "false" )
115 private boolean useDefaultManifestFile;
116
117
118
119
120 @Component
121 private MavenProjectHelper projectHelper;
122
123
124
125
126
127
128
129
130
131
132
133
134 @Parameter( property = "maven.jar.forceCreation", defaultValue = "false" )
135 private boolean forceCreation;
136
137
138
139
140 @Parameter( defaultValue = "false" )
141 private boolean skipIfEmpty;
142
143
144
145
146
147
148
149
150 @Parameter( defaultValue = "${project.build.outputTimestamp}" )
151 private String outputTimestamp;
152
153
154
155
156
157 protected abstract File getClassesDirectory();
158
159
160
161
162 protected final MavenProject getProject()
163 {
164 return project;
165 }
166
167
168
169
170
171 protected abstract String getClassifier();
172
173
174
175
176
177 protected abstract String getType();
178
179
180
181
182
183
184
185
186
187 protected File getJarFile( File basedir, String resultFinalName, String classifier )
188 {
189 if ( basedir == null )
190 {
191 throw new IllegalArgumentException( "basedir is not allowed to be null" );
192 }
193 if ( resultFinalName == null )
194 {
195 throw new IllegalArgumentException( "finalName is not allowed to be null" );
196 }
197
198 StringBuilder fileName = new StringBuilder( resultFinalName );
199
200 if ( hasClassifier() )
201 {
202 fileName.append( "-" ).append( classifier );
203 }
204
205 fileName.append( ".jar" );
206
207 return new File( basedir, fileName.toString() );
208 }
209
210
211
212
213
214
215 public File createArchive()
216 throws MojoExecutionException
217 {
218 File jarFile = getJarFile( outputDirectory, finalName, getClassifier() );
219
220 FileSetManager fileSetManager = new FileSetManager();
221 FileSet jarContentFileSet = new FileSet();
222 jarContentFileSet.setDirectory( getClassesDirectory().getAbsolutePath() );
223 jarContentFileSet.setIncludes( Arrays.asList( getIncludes() ) );
224 jarContentFileSet.setExcludes( Arrays.asList( getExcludes() ) );
225
226 boolean containsModuleDescriptor = false;
227 String[] includedFiles = fileSetManager.getIncludedFiles( jarContentFileSet );
228 for ( String includedFile : includedFiles )
229 {
230
231
232
233
234
235
236
237
238 if ( includedFile.endsWith( MODULE_DESCRIPTOR_FILE_NAME ) )
239 {
240 containsModuleDescriptor = true;
241 break;
242 }
243 }
244
245 MavenArchiver archiver = new MavenArchiver();
246 archiver.setCreatedBy( "Maven JAR Plugin", "org.apache.maven.plugins", "maven-jar-plugin" );
247
248 if ( containsModuleDescriptor )
249 {
250 archiver.setArchiver( (JarArchiver) archivers.get( "mjar" ) );
251 }
252 else
253 {
254 archiver.setArchiver( (JarArchiver) archivers.get( "jar" ) );
255 }
256
257 archiver.setOutputFile( jarFile );
258
259
260 archiver.configureReproducible( outputTimestamp );
261
262 archive.setForced( forceCreation );
263
264 try
265 {
266 File contentDirectory = getClassesDirectory();
267 if ( !contentDirectory.exists() )
268 {
269 if ( !forceCreation )
270 {
271 getLog().warn( "JAR will be empty - no content was marked for inclusion!" );
272 }
273 }
274 else
275 {
276 archiver.getArchiver().addDirectory( contentDirectory, getIncludes(), getExcludes() );
277 }
278
279 archiver.createArchive( session, project, archive );
280
281 return jarFile;
282 }
283 catch ( Exception e )
284 {
285
286 throw new MojoExecutionException( "Error assembling JAR", e );
287 }
288 }
289
290
291
292
293
294 public void execute()
295 throws MojoExecutionException
296 {
297 if ( useDefaultManifestFile )
298 {
299 throw new MojoExecutionException( "You are using 'useDefaultManifestFile' which has been removed"
300 + " from the maven-jar-plugin. "
301 + "Please see the >>Major Version Upgrade to version 3.0.0<< on the plugin site." );
302 }
303
304 if ( skipIfEmpty && ( !getClassesDirectory().exists() || getClassesDirectory().list().length < 1 ) )
305 {
306 getLog().info( "Skipping packaging of the " + getType() );
307 }
308 else
309 {
310 File jarFile = createArchive();
311
312 if ( hasClassifier() )
313 {
314 projectHelper.attachArtifact( getProject(), getType(), getClassifier(), jarFile );
315 }
316 else
317 {
318 if ( projectHasAlreadySetAnArtifact() )
319 {
320 throw new MojoExecutionException( "You have to use a classifier "
321 + "to attach supplemental artifacts to the project instead of replacing them." );
322 }
323 getProject().getArtifact().setFile( jarFile );
324 }
325 }
326 }
327
328 private boolean projectHasAlreadySetAnArtifact()
329 {
330 if ( getProject().getArtifact().getFile() != null )
331 {
332 return getProject().getArtifact().getFile().isFile();
333 }
334 else
335 {
336 return false;
337 }
338 }
339
340
341
342
343 protected boolean hasClassifier()
344 {
345 boolean result = false;
346 if ( getClassifier() != null && getClassifier().trim().length() > 0 )
347 {
348 result = true;
349 }
350
351 return result;
352 }
353
354 private String[] getIncludes()
355 {
356 if ( includes != null && includes.length > 0 )
357 {
358 return includes;
359 }
360 return DEFAULT_INCLUDES;
361 }
362
363 private String[] getExcludes()
364 {
365 if ( excludes != null && excludes.length > 0 )
366 {
367 return excludes;
368 }
369 return DEFAULT_EXCLUDES;
370 }
371 }