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 getLog().warn( "JAR will be empty - no content was marked for inclusion!" );
270 }
271 else
272 {
273 archiver.getArchiver().addDirectory( contentDirectory, getIncludes(), getExcludes() );
274 }
275
276 archiver.createArchive( session, project, archive );
277
278 return jarFile;
279 }
280 catch ( Exception e )
281 {
282
283 throw new MojoExecutionException( "Error assembling JAR", e );
284 }
285 }
286
287
288
289
290
291 public void execute()
292 throws MojoExecutionException
293 {
294 if ( useDefaultManifestFile )
295 {
296 throw new MojoExecutionException( "You are using 'useDefaultManifestFile' which has been removed"
297 + " from the maven-jar-plugin. "
298 + "Please see the >>Major Version Upgrade to version 3.0.0<< on the plugin site." );
299 }
300
301 if ( skipIfEmpty && ( !getClassesDirectory().exists() || getClassesDirectory().list().length < 1 ) )
302 {
303 getLog().info( "Skipping packaging of the " + getType() );
304 }
305 else
306 {
307 File jarFile = createArchive();
308
309 if ( hasClassifier() )
310 {
311 projectHelper.attachArtifact( getProject(), getType(), getClassifier(), jarFile );
312 }
313 else
314 {
315 if ( projectHasAlreadySetAnArtifact() )
316 {
317 throw new MojoExecutionException( "You have to use a classifier "
318 + "to attach supplemental artifacts to the project instead of replacing them." );
319 }
320 getProject().getArtifact().setFile( jarFile );
321 }
322 }
323 }
324
325 private boolean projectHasAlreadySetAnArtifact()
326 {
327 if ( getProject().getArtifact().getFile() != null )
328 {
329 return getProject().getArtifact().getFile().isFile();
330 }
331 else
332 {
333 return false;
334 }
335 }
336
337
338
339
340 protected boolean hasClassifier()
341 {
342 boolean result = false;
343 if ( getClassifier() != null && getClassifier().trim().length() > 0 )
344 {
345 result = true;
346 }
347
348 return result;
349 }
350
351 private String[] getIncludes()
352 {
353 if ( includes != null && includes.length > 0 )
354 {
355 return includes;
356 }
357 return DEFAULT_INCLUDES;
358 }
359
360 private String[] getExcludes()
361 {
362 if ( excludes != null && excludes.length > 0 )
363 {
364 return excludes;
365 }
366 return DEFAULT_EXCLUDES;
367 }
368 }