public static void createJar(Project prj, Path compileDir, Path jarFile) throws IOException {
		Manifest manifest = new Manifest();
		manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");

		prj.getManifestAttributes().forEach((k, v) -> manifest.getMainAttributes().putValue(k, v));

		int buildJdk = prj.projectJdk().majorVersion();
		if (buildJdk > 0) {
			String val = buildJdk >= 9 ? Integer.toString(buildJdk) : "1." + buildJdk;
			manifest.getMainAttributes().putValue(ATTR_BUILD_JDK, val);
		}

		JarUtil.createJar(jarFile, compileDir, manifest, prj.getMainClass(), prj.projectJdk());

		if (AppBuilder.keepClasses()) {
			// In the case the "keep classes" option is specified we write
			// an extra copy if the manifest to its proper location.
			// This file is never used but is there so the user can take
			// a look at it and know what its contents are
			String mainclass = prj.getMainClass();
			if (mainclass != null) {
				manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, mainclass);
			}
			Path mf = compileDir.resolve("META-INF/MANIFEST.MF");
			try (OutputStream os = Files.newOutputStream(mf)) {
				manifest.write(os);
			}
		}
	}
This class takes a <code>Project</code> and the result from a previous
"compile" step and packages the whole into a JAR file.
src/main/java/dev/jbang/source/buildsteps/JarBuildStep.java