void configureManifest(Manifest manifest) { // set manifest entries from Moxie metadata Manifest mft = new Manifest(); setManifest(mft, "Created-By", "Moxie v" + Toolkit.getVersion()); setManifest(mft, "Build-Jdk", System.getProperty("java.version")); setManifest(mft, "Build-Date", new SimpleDateFormat("yyyy-MM-dd").format(new Date())); setManifest(mft, "Implementation-Title", Key.name); setManifest(mft, "Implementation-Vendor", Key.organization); setManifest(mft, "Implementation-Vendor-Id", Key.groupId); setManifest(mft, "Implementation-Vendor-URL", Key.url); setManifest(mft, "Implementation-Version", Key.version); setManifest(mft, "Bundle-Name", Key.name); setManifest(mft, "Bundle-SymbolicName", Key.artifactId); setManifest(mft, "Bundle-Version", Key.version); setManifest(mft, "Bundle-Vendor", Key.organization); setManifest(mft, "Maven-Url", Key.mavenUrl); setManifest(mft, "Commit-Id", Key.commitId); try { manifest.merge(mft, true); } catch (ManifestException e) { console.error(e, "Failed to configure manifest!"); } }
void setManifest(Manifest man, String key, String value) { if (!StringUtils.isEmpty(value)) { try { man.addConfiguredAttribute(new Attribute(key, value)); } catch (ManifestException e) { console.error(e, "Failed to set manifest attribute \"{0}\"!", key); } } }
/** Add the Maven META-INF files. */ @Override protected void writeJarEntries(JarOutputStream jos) { if (excludePomFiles) { return; } DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(jos)); Properties properties = new Properties(); properties.put(Key.groupId.name(), build.getPom().groupId); properties.put(Key.artifactId.name(), build.getPom().artifactId); properties.put(Key.version.name(), version); try { ZipEntry entry = new ZipEntry( MessageFormat.format( "META-INF/maven/{0}/{1}/pom.properties", build.getPom().groupId, build.getPom().artifactId)); jos.putNextEntry(entry); properties.store(dos, "Generated by Moxie"); dos.flush(); jos.closeEntry(); } catch (IOException e) { console.error(e, "failed to write pom.properties!"); } try { ZipEntry entry = new ZipEntry( MessageFormat.format( "META-INF/maven/{0}/{1}/pom.xml", build.getPom().groupId, build.getPom().artifactId)); jos.putNextEntry(entry); dos.write(build.getPom().toXML(false).getBytes("UTF-8")); dos.flush(); jos.closeEntry(); } catch (IOException e) { console.error(e, "failed to write pom.xml!"); } }
@Override public void execute() throws BuildException { build = (Build) getProject().getReference(Key.build.referenceId()); console = build.getConsole(); if (!configured) { // called from moxie.package configure(build); } if (fatjar && excludeClasspathJars) { throw new BuildException("Can not specify fatjar and excludeClasspathJars!"); } // automatic manifest entries from Moxie metadata configureManifest(mft); if (mainclass == null) { String mc = build.getConfig().getProjectConfig().getMainclass(); if (!StringUtils.isEmpty(mc)) { ClassSpec cs = new ClassSpec(getProject()); mainclass = cs; mainclass.setName(mc); jarSpecs.add(cs); } } if (mainclass != null) { String mc = mainclass.getName().replace('/', '.'); if (mc.endsWith(".class")) { mc = mc.substring(0, mc.length() - ".class".length()); } if (launcher == null) { // use specified mainclass setManifest(mft, "Main-Class", mc); } else { // inject Moxie Launcher class String mx = launcher.getName().replace('/', '.'); if (mx.endsWith(".class")) { mx = mx.substring(0, mx.length() - ".class".length()); } setManifest(mft, "Main-Class", mx); setManifest(mft, "mxMain-Class", mc); String paths = launcher.getPaths(); if (!StringUtils.isEmpty(paths)) { setManifest(mft, "mxMain-Paths", paths); } } } // automatic classpath resolution, if not manually specified if (classpath == null) { Path cp = buildClasspath(build, Scope.compile, tag); if (fatjar) { // FatJar generation classpath = createClasspath(); for (String path : cp.list()) { if (path.toLowerCase().endsWith(".jar")) { LibrarySpec lib = createLibrary(); lib.setJar(path); } else { PathElement element = classpath.createPathElement(); element.setPath(path); } } } else { // standard GenJar class dependency resolution classpath = cp; } } if (destFile == null) { setDestfile(build.getBuildArtifact(classifier)); } if (destFile.getParentFile() != null) { destFile.getParentFile().mkdirs(); } version = build.getPom().version; File outputFolder = build.getConfig().getOutputDirectory(Scope.compile); if (excludes == null) { excludes = Toolkit.DEFAULT_RESOURCE_EXCLUDES; } // include resources from the project source folders Resource resources = createResource(); if (!StringUtils.isEmpty(resourceFolderPrefix)) { resources.setPrefix(resourceFolderPrefix); } for (File dir : build.getConfig().getSourceDirectories(Scope.compile, tag)) { FileSet res = resources.createFileset(); res.setDir(dir); res.setExcludes(excludes); } if (includeResources) { // include resources from the project resource folders for (File dir : build.getConfig().getResourceDirectories(Scope.compile, tag)) { FileSet res = resources.createFileset(); res.setExcludes(excludes); res.setDir(dir); } for (Build module : build.getSolver().getLinkedModules()) { // include resources from module source folders File dir = module.getConfig().getOutputDirectory(Scope.compile); FileSet res = resources.createFileset(); res.setDir(dir); res.setExcludes(excludes); // include resources from the module resource folders for (File resDir : module.getConfig().getResourceDirectories(Scope.compile)) { FileSet resSet = resources.createFileset(); res.setExcludes(Toolkit.DEFAULT_RESOURCE_EXCLUDES); resSet.setDir(resDir); } } } if (isShowTitle()) { console.title(getClass(), destFile.getName()); } console.debug(getTaskName() + " configuration"); // display specified mxgenjar attributes MaxmlMap attributes = build.getConfig().getTaskAttributes(getTaskName()); AttributeReflector.logAttributes(this, attributes, console); // optionally inject MxLauncher utility if (launcher != null) { if (launcher.getName().equals(MxLauncher.class.getName().replace('.', '/') + ".class")) { // inject MxLauncher into the output folder of the project for (String cn : Arrays.asList(MxLauncher.class.getName(), MxLauncher.class.getName() + "$1")) { try { String fn = cn.replace('.', '/') + ".class"; InputStream is = MxLauncher.class.getResourceAsStream("/" + fn); if (is == null) { continue; } build.getConsole().log("Injecting {0} into output folder", cn); File file = new File(outputFolder, fn.replace('/', File.separatorChar)); if (file.exists()) { file.delete(); } file.getParentFile().mkdirs(); FileOutputStream os = new FileOutputStream(file, false); byte[] buffer = new byte[4096]; int len = 0; while ((len = is.read(buffer)) > 0) { os.write(buffer, 0, len); } is.close(); os.flush(); os.close(); // add these files to the jarSpecs ClassSpec cs = new ClassSpec(getProject()); cs.setName(cn); jarSpecs.add(cs); } catch (Exception e) { build .getConsole() .error(e, "Failed to inject {0} into {1}", launcher.getName(), outputFolder); } } } } long start = System.currentTimeMillis(); try { super.execute(); } catch (ResolutionFailedException e) { String msg; if (tag == null) { String template = "Unable to resolve: {0}\n\n{1} could not be located on the classpath.\n"; msg = MessageFormat.format( template, e.resolvingclass, e.missingclass, tag == null ? "classpath" : ("\"" + tag + "\" classpath"), tag); } else { String template = "Unable to resolve: {0}\n\n{1} could not be located on the \"{2}\" classpath.\nPlease add the \":{2}\" tag to the appropriate dependency in your Moxie descriptor file.\n"; msg = MessageFormat.format(template, e.resolvingclass, e.missingclass, tag); } throw new MoxieException(msg); } if (fatjar) { // try to merge duplicate META-INF/services files JarUtils.mergeMetaInfServices(console, destFile); } console.log(1, destFile.getAbsolutePath()); console.log( 1, "{0} KB, generated in {1} ms", (destFile.length() / 1024), System.currentTimeMillis() - start); /* * Build sources jar */ if (packageSources) { String name = destFile.getName(); if (!StringUtils.isEmpty(classifier)) { // replace the classifier with "sources" name = name.replace(classifier, "sources"); } else { // append -sources to the filename before the extension name = name.substring(0, name.lastIndexOf('.')) + "-sources" + name.substring(name.lastIndexOf('.')); } File sourcesFile = new File(destFile.getParentFile(), name); if (sourcesFile.exists()) { sourcesFile.delete(); } Jar jar = new Jar(); jar.setTaskName(getTaskName()); jar.setProject(getProject()); // set the destination file jar.setDestFile(sourcesFile); // use the resolved classes to determine included source files List<FileResource> sourceFiles = new ArrayList<FileResource>(); Map<File, Set<String>> packageResources = new HashMap<File, Set<String>>(); if (resolvedLocal.size() == 0) { console.warn( getTaskName() + " has not resolved any class files local to {0}", build.getPom().getManagementId()); } List<File> folders = build.getConfig().getSourceDirectories(Scope.compile, tag); for (String className : resolvedLocal) { String sourceName = className.substring(0, className.length() - ".class".length()).replace('.', '/') + ".java"; console.debug(sourceName); for (File folder : folders) { File file = new File(folder, sourceName); if (file.exists()) { FileResource resource = new FileResource(getProject(), file); resource.setBaseDir(folder); sourceFiles.add(resource); if (!packageResources.containsKey(folder)) { // always include default package resources packageResources.put(folder, new TreeSet<String>(Arrays.asList("/*"))); } String packagePath = FileUtils.getRelativePath(folder, file.getParentFile()); packageResources.get(folder).add(packagePath + "/*"); console.debug(1, file.getAbsolutePath()); break; } } } // add the discovered source files for the resolved classes jar.add(new FileResourceSet(sourceFiles)); // add the resolved package folders for resource files for (Map.Entry<File, Set<String>> entry : packageResources.entrySet()) { FileSet res = new FileSet(); res.setDir(entry.getKey()); res.setExcludes(excludes); StringBuilder includes = new StringBuilder(); for (String packageName : entry.getValue()) { includes.append(packageName + ","); } includes.setLength(includes.length() - 1); res.setIncludes(includes.toString()); console.debug("adding resource fileset {0}", entry.getKey()); console.debug(1, "includes={0}", includes.toString()); jar.add(res); } if (includeResources) { for (File dir : build.getConfig().getResourceDirectories(Scope.compile, tag)) { FileSet res = resources.createFileset(); res.setDir(dir); res.setExcludes(Toolkit.DEFAULT_RESOURCE_EXCLUDES); jar.add(res); } } // set the source jar manifest try { Manifest mft = new Manifest(); configureManifest(mft); jar.addConfiguredManifest(mft); } catch (ManifestException e) { console.error(e); } start = System.currentTimeMillis(); jar.execute(); console.log(1, sourcesFile.getAbsolutePath()); console.log( 1, "{0} KB, generated in {1} ms", (sourcesFile.length() / 1024), System.currentTimeMillis() - start); } }