/** Check if the getSubBuilders properly predicts the output. */ public static void testSubBuilders() throws Exception { Workspace ws = Workspace.getWorkspace(new File("test/ws")); Project project = ws.getProject("p4-sub"); Collection<? extends Builder> bs = project.getSubBuilders(); assertNotNull(bs); assertEquals(3, bs.size()); Set<String> names = new HashSet<String>(); for (Builder b : bs) { names.add(b.getBsn()); } assertTrue(names.contains("p4-sub.a")); assertTrue(names.contains("p4-sub.b")); assertTrue(names.contains("p4-sub.c")); File[] files = project.build(); assertTrue(project.check()); System.err.println(Processor.join(project.getErrors(), "\n")); System.err.println(Processor.join(project.getWarnings(), "\n")); assertEquals(0, project.getErrors().size()); assertEquals(0, project.getWarnings().size()); assertNotNull(files); assertEquals(3, files.length); for (File file : files) { Jar jar = new Jar(file); Manifest m = jar.getManifest(); assertTrue(names.contains(m.getMainAttributes().getValue("Bundle-SymbolicName"))); } }
/** * Read the version information from a file with a given file name. The file must be a jar * manifest file and all its entries are searched for package names and their specification * version information. All information is collected in a map for later lookup of package names * and their versions. * * @param versionFileName name of the jar file containing version information */ public static String readVersionFromFile(String applicationName, String versionFileName) { try { FileInputStream fileInput = new FileInputStream(versionFileName); Manifest manifest = new Manifest(); manifest.read(fileInput); Map entries = manifest.getEntries(); // Now write out the pre-entry attributes Iterator entryIterator = entries.entrySet().iterator(); while (entryIterator.hasNext()) { Map.Entry currentEntry = (Map.Entry) entryIterator.next(); String packageName = currentEntry.getKey().toString(); packageName = normalizePackageName(packageName); Attributes attributes = (Attributes) currentEntry.getValue(); String packageSpecVersion = attributes.getValue(Attributes.Name.SPECIFICATION_VERSION); packageSpecVersion = extractVersionInfo(packageSpecVersion); return packageSpecVersion; } } catch (IOException exception) { exception.printStackTrace(); } // no version found return null; }
public static boolean extractJarDir(String jarfile, String outfile) throws Exception { long filesize = new File(jarfile).length(); JarInputStream jar = new JarInputStream(new FileInputStream(jarfile)); // while (true) { // JarEntry jarentry = (JarEntry)jar.getNextJarEntry(); // if (jarentry==null) break; // String maindir = jarentry.getName(); // // get rid of "./" and "/" prefix // if (maindir.startsWith(".")) // maindir = maindir.substring(1); // if (maindir.startsWith(File.separator)) // maindir = maindir.substring(1); // // Find manifest // System.out.println(maindir); // if (maindir.equals("META-INF/MANIFEST.MF")) { // java.io.InputStream ins = jar; java.io.FileOutputStream outs = new java.io.FileOutputStream(outfile); Manifest man = jar.getManifest(); if (man == null) return false; man.write(outs); byte[] buf = ("MIDlet-Jar-Size: " + filesize).getBytes(); outs.write(buf, 0, buf.length); outs.close(); // // copy buffered (is a lot faster than one byte at a time) // byte[] buf = new byte[8192]; // int total_bytes=0; // while (true) { // //outs.write(ins.read()); // int len = ins.read(buf); // if (len < 0) break; // outs.write(buf,0,len); // total_bytes += len; // } // buf = ("MIDlet-Jar-Size: "+total_bytes).getBytes(); // outs.write(buf,0,buf.length); // outs.close(); // //ins.close(); // } // } // return false; // remove empty lines from the generated jad which may have been // introduced by manifest write. // some systems have trouble with empty lines List<String> lines = new ArrayList<String>(); BufferedReader in = new BufferedReader(new FileReader(outfile)); while (true) { String line = in.readLine(); if (line == null) break; lines.add(line); } in.close(); PrintWriter outp = new PrintWriter(outfile); for (String s : lines) { if (s.trim().equals("")) continue; outp.println(s); } outp.close(); return true; }
protected void addPathFile(final File pathComponent) throws IOException { if (!this.pathComponents.contains(pathComponent)) { this.pathComponents.addElement(pathComponent); } if (pathComponent.isDirectory()) { return; } final String absPathPlusTimeAndLength = pathComponent.getAbsolutePath() + pathComponent.lastModified() + "-" + pathComponent.length(); String classpath = AntClassLoader.pathMap.get(absPathPlusTimeAndLength); if (classpath == null) { JarFile jarFile = null; try { jarFile = new JarFile(pathComponent); final Manifest manifest = jarFile.getManifest(); if (manifest == null) { return; } classpath = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH); } finally { if (jarFile != null) { jarFile.close(); } } if (classpath == null) { classpath = ""; } AntClassLoader.pathMap.put(absPathPlusTimeAndLength, classpath); } if (!"".equals(classpath)) { final URL baseURL = AntClassLoader.FILE_UTILS.getFileURL(pathComponent); final StringTokenizer st = new StringTokenizer(classpath); while (st.hasMoreTokens()) { final String classpathElement = st.nextToken(); final URL libraryURL = new URL(baseURL, classpathElement); if (!libraryURL.getProtocol().equals("file")) { this.log( "Skipping jar library " + classpathElement + " since only relative URLs are supported by this" + " loader", 3); } else { final String decodedPath = Locator.decodeUri(libraryURL.getFile()); final File libraryFile = new File(decodedPath); if (!libraryFile.exists() || this.isInPath(libraryFile)) { continue; } this.addPathFile(libraryFile); } } } }
// optimal side-effects private synchronized boolean isSuperMan() throws IOException { if (superMan == null) { superMan = super.getManifest(); } if (superMan != null) { superAttr = superMan.getMainAttributes(); superEntries = superMan.getEntries(); return true; } else return false; }
/** Test default package versions. */ public static void testDefaultPackageVersion() throws Exception { Builder a = new Builder(); a.addClasspath(new File("bin")); a.setProperty("Bundle-Version", "1.2.3"); a.setProperty("Export-Package", "test.refer"); Jar jar = a.build(); Manifest m = jar.getManifest(); Parameters exports = Processor.parseHeader(m.getMainAttributes().getValue(Constants.EXPORT_PACKAGE), null); Map<String, String> attrs = exports.get("test.refer"); assertNotNull(attrs); assertEquals("1.2.3", attrs.get("version")); }
/** Test import provide:. */ public static void testExportProvided() throws Exception { Builder a = new Builder(); a.addClasspath(IO.getFile("jar/osgi.jar")); a.addClasspath(new File("bin")); a.setProperty("Private-Package", "test.refer"); a.setProperty("Export-Package", "org.osgi.service.http;provide:=true"); Jar jar = a.build(); Map<String, String> event = a.getImports().getByFQN("org.osgi.service.event"); assertEquals("[1.0,2)", event.get("version")); Map<String, String> http = a.getImports().getByFQN("org.osgi.service.http"); assertEquals("[1.2,1.3)", http.get("version")); Manifest m = jar.getManifest(); String imports = m.getMainAttributes().getValue(Constants.IMPORT_PACKAGE); assertFalse(imports.contains(Constants.PROVIDE_DIRECTIVE)); }
/** hardcoded imports */ public static void testHardcodedImports() throws Exception { Builder b = new Builder(); b.addClasspath(IO.getFile("jar/osgi.jar")); b.setProperty("-versionpolicy", "${range;[==,+)}"); b.setProperty("Private-Package", "org.objectweb.asm"); b.setProperty("Import-Package", "org.osgi.framework,org.objectweb.asm,abc;version=2.0.0,*"); b.build(); Manifest m = b.getJar().getManifest(); m.write(System.err); String s = b.getImports().getByFQN("org.objectweb.asm").get("version"); assertNull(s); s = b.getImports().getByFQN("abc").get("version"); assertEquals("2.0.0", s); s = b.getImports().getByFQN("org.osgi.framework").get("version"); assertEquals("[1.3,2)", s); }
/** * Tests if the implementation of the EventHandler (which is marked as a ConsumerType) causes the * import of the api package to use the consumer version policy. */ public static void testConsumerType() throws Exception { Builder a = new Builder(); a.addClasspath(new File("bin")); a.setPrivatePackage("test.versionpolicy.uses"); a.setExportPackage("test.versionpolicy.api"); a.setProperty("build", "123"); Jar jar = a.build(); assertTrue(a.check()); Manifest m = jar.getManifest(); m.write(System.err); Domain d = Domain.domain(m); Parameters parameters = d.getImportPackage(); Attrs attrs = parameters.get("test.versionpolicy.api"); assertNotNull(attrs); assertEquals("[1.2,2)", attrs.get("version")); }
/** * Test if the implementation of "AnnotatedProviderInterface", which is annotated with OSGi * R6 @ProviderType, causes import of the api package to use the provider version policy */ public static void testProviderTypeR6() throws Exception { Builder b = new Builder(); b.addClasspath(new File("bin")); b.setPrivatePackage("test.versionpolicy.implemented.osgi"); b.setProperty("build", "123"); Jar jar = b.build(); assertTrue(b.check()); Manifest m = jar.getManifest(); m.write(System.err); Domain d = Domain.domain(m); Parameters params = d.getImportPackage(); Attrs attrs = params.get("test.version.annotations.osgi"); assertNotNull(attrs); assertEquals("[1.2,1.3)", attrs.get("version")); }
private static String getVersionString() { String findContainingJar = JarManager.findContainingJar(Main.class); try { StringBuffer buffer = new StringBuffer(); JarFile jar = new JarFile(findContainingJar); final Manifest manifest = jar.getManifest(); final Map<String, Attributes> attrs = manifest.getEntries(); Attributes attr = attrs.get("org/apache/pig"); String version = (String) attr.getValue("Implementation-Version"); String svnRevision = (String) attr.getValue("Svn-Revision"); String buildTime = (String) attr.getValue("Build-TimeStamp"); // we use a version string similar to svn // svn, version 1.4.4 (r25188) // compiled Sep 23 2007, 22:32:34 return "Apache Pig version " + version + " (r" + svnRevision + ") \ncompiled " + buildTime; } catch (Exception e) { throw new RuntimeException("unable to read pigs manifest file", e); } }
/** * Tests if the implementation of the EventAdmin (which is marked as a ProviderType) causes the * import of the api package to use the provider version policy. */ public static void testProviderType() throws Exception { Builder a = new Builder(); a.addClasspath(new File("bin")); a.setPrivatePackage("test.versionpolicy.implemented"); a.setExportPackage("test.versionpolicy.api"); a.setImportPackage("test.versionpolicy.api"); // what changed so this is // not automatically // added? a.setProperty("build", "123"); Jar jar = a.build(); assertTrue(a.check()); Manifest m = jar.getManifest(); m.write(System.err); Domain d = Domain.domain(m); Parameters parameters = d.getImportPackage(); Attrs attrs = parameters.get("test.versionpolicy.api"); assertNotNull(attrs); assertEquals("[1.2,1.3)", attrs.get("version")); }
public String verify(JarFile jar, String... algorithms) throws IOException { if (algorithms == null || algorithms.length == 0) algorithms = new String[] {"MD5", "SHA"}; else if (algorithms.length == 1 && algorithms[0].equals("-")) return null; try { Manifest m = jar.getManifest(); if (m.getEntries().isEmpty()) return "No name sections"; for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements(); ) { JarEntry je = e.nextElement(); if (MANIFEST_ENTRY.matcher(je.getName()).matches()) continue; Attributes nameSection = m.getAttributes(je.getName()); if (nameSection == null) return "No name section for " + je.getName(); for (String algorithm : algorithms) { try { MessageDigest md = MessageDigest.getInstance(algorithm); String expected = nameSection.getValue(algorithm + "-Digest"); if (expected != null) { byte digest[] = Base64.decodeBase64(expected); copy(jar.getInputStream(je), md); if (!Arrays.equals(digest, md.digest())) return "Invalid digest for " + je.getName() + ", " + expected + " != " + Base64.encodeBase64(md.digest()); } else reporter.error("could not find digest for " + algorithm + "-Digest"); } catch (NoSuchAlgorithmException nsae) { return "Missing digest algorithm " + algorithm; } } } } catch (Exception e) { return "Failed to verify due to exception: " + e.getMessage(); } return null; }
private static Hashtable<String, String> getManifestAttributes(Manifest manifest) { Hashtable<String, String> h = new Hashtable<String, String>(); try { Attributes attrs = manifest.getMainAttributes(); Iterator it = attrs.keySet().iterator(); while (it.hasNext()) { String key = it.next().toString(); h.put(key, attrs.getValue(key)); } } catch (Exception ignore) { } return h; }
/** * We create a JAR with the test.classreferenc.ClassReference class. This class contains a * javax.swing.Box.class reference Prior to Java 1.5, this was done in a silly way that is handled * specially. After 1.5 it is a normal reference. * * @throws Exception */ public void testReference() throws Exception { Properties properties = new Properties(); properties.put("-classpath", "compilerversions/compilerversions.jar"); String[] packages = { "sun_1_1", "sun_1_6", "eclipse_1_1", "sun_1_2", "sun_1_3", "sun_1_4", "sun_1_5", "sun_jsr14", "eclipse_1_5", "eclipse_1_6", "eclipse_1_2", "eclipse_1_3", "eclipse_1_4", "eclipse_jsr14" }; for (int i = 0; i < packages.length; i++) { Builder builder = new Builder(); properties.put("Export-Package", packages[i]); builder.setProperties(properties); Jar jar = builder.build(); System.out.println(builder.getErrors()); System.out.println(builder.getWarnings()); assertEquals(0, builder.getErrors().size()); assertEquals(0, builder.getWarnings().size()); Manifest manifest = jar.getManifest(); String imports = manifest.getMainAttributes().getValue("Import-Package"); assertTrue( "Package " + packages[i] + "contains swing ref", imports.indexOf("javax.swing") >= 0); assertFalse( "Package " + packages[i] + "should not contain ClassRef", imports.indexOf("ClassRef") >= 0); } }
/** Check implementation version policy. Uses the package test.versionpolicy.(uses|implemented) */ static void assertPolicy(String pack, String type) throws Exception { Builder a = new Builder(); a.addClasspath(new File("bin")); a.setProperty("Export-Package", "test.versionpolicy.api"); Jar jar = a.build(); Builder b = new Builder(); b.addClasspath(jar); b.addClasspath(new File("bin")); b.setProperty("-versionpolicy-impl", "IMPL"); b.setProperty("-versionpolicy-uses", "USES"); b.setProperty("Private-Package", pack); b.build(); Manifest m = b.getJar().getManifest(); m.write(System.err); Map<String, String> map = b.getImports().getByFQN("test.versionpolicy.api"); assertNotNull(map); // String s = map.get(Constants.IMPLEMENTED_DIRECTIVE); // assertEquals("true", s); Parameters mp = Processor.parseHeader(m.getMainAttributes().getValue("Import-Package"), null); assertEquals(type, mp.get("test.versionpolicy.api").get("version")); }
public Manifest getManifest() throws IOException { if (!isSuperMan()) { return null; } Manifest man = new Manifest(); Attributes attr = man.getMainAttributes(); attr.putAll((Map) superAttr.clone()); // now deep copy the manifest entries if (superEntries != null) { Map entries = man.getEntries(); Iterator it = superEntries.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); Attributes at = (Attributes) superEntries.get(key); entries.put(key, at.clone()); } } return man; }
/** * Tests the handling of the -sub facility * * @throws Exception */ public static void testSub() throws Exception { Workspace ws = Workspace.getWorkspace(new File("test/ws")); Project project = ws.getProject("p4-sub"); File[] files = project.build(); Arrays.sort(files); System.err.println(Processor.join(project.getErrors(), "\n")); System.err.println(Processor.join(project.getWarnings(), "\n")); assertEquals(0, project.getErrors().size()); assertEquals(0, project.getWarnings().size()); assertNotNull(files); assertEquals(3, files.length); Jar a = new Jar(files[0]); Jar b = new Jar(files[1]); Manifest ma = a.getManifest(); Manifest mb = b.getManifest(); assertEquals("base", ma.getMainAttributes().getValue("Base-Header")); assertEquals("base", mb.getMainAttributes().getValue("Base-Header")); assertEquals("a", ma.getMainAttributes().getValue("Sub-Header")); assertEquals("b", mb.getMainAttributes().getValue("Sub-Header")); }
protected void definePackage( final File container, final String packageName, final Manifest manifest) { final String sectionName = packageName.replace('.', '/') + "/"; String specificationTitle = null; String specificationVendor = null; String specificationVersion = null; String implementationTitle = null; String implementationVendor = null; String implementationVersion = null; String sealedString = null; URL sealBase = null; final Attributes sectionAttributes = manifest.getAttributes(sectionName); if (sectionAttributes != null) { specificationTitle = sectionAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE); specificationVendor = sectionAttributes.getValue(Attributes.Name.SPECIFICATION_VENDOR); specificationVersion = sectionAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION); implementationTitle = sectionAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE); implementationVendor = sectionAttributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR); implementationVersion = sectionAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION); sealedString = sectionAttributes.getValue(Attributes.Name.SEALED); } final Attributes mainAttributes = manifest.getMainAttributes(); if (mainAttributes != null) { if (specificationTitle == null) { specificationTitle = mainAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE); } if (specificationVendor == null) { specificationVendor = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VENDOR); } if (specificationVersion == null) { specificationVersion = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION); } if (implementationTitle == null) { implementationTitle = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE); } if (implementationVendor == null) { implementationVendor = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR); } if (implementationVersion == null) { implementationVersion = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION); } if (sealedString == null) { sealedString = mainAttributes.getValue(Attributes.Name.SEALED); } } if (sealedString != null && sealedString.equalsIgnoreCase("true")) { try { sealBase = new URL(FileUtils.getFileUtils().toURI(container.getAbsolutePath())); } catch (MalformedURLException ex) { } } this.definePackage( packageName, specificationTitle, specificationVersion, specificationVendor, implementationTitle, implementationVersion, implementationVendor, sealBase); }
public void signJar(Jar jar) { if (digestNames == null || digestNames.length == 0) error("Need at least one digest algorithm name, none are specified"); if (keystoreFile == null || !keystoreFile.getAbsoluteFile().exists()) { error("No such keystore file: " + keystoreFile); return; } if (alias == null) { error("Private key alias not set for signing"); return; } MessageDigest digestAlgorithms[] = new MessageDigest[digestNames.length]; getAlgorithms(digestNames, digestAlgorithms); try { Manifest manifest = jar.getManifest(); manifest.getMainAttributes().putValue("Signed-By", "Bnd"); // Create a new manifest that contains the // Name parts with the specified digests ByteArrayOutputStream o = new ByteArrayOutputStream(); manifest.write(o); doManifest(jar, digestNames, digestAlgorithms, o); o.flush(); byte newManifestBytes[] = o.toByteArray(); jar.putResource("META-INF/MANIFEST.MF", new EmbeddedResource(newManifestBytes, 0)); // Use the bytes from the new manifest to create // a signature file byte[] signatureFileBytes = doSignatureFile(digestNames, digestAlgorithms, newManifestBytes); jar.putResource("META-INF/BND.SF", new EmbeddedResource(signatureFileBytes, 0)); // Now we must create an RSA signature // this requires the private key from the keystore KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); KeyStore.PrivateKeyEntry privateKeyEntry = null; java.io.FileInputStream keystoreInputStream = null; try { keystoreInputStream = new java.io.FileInputStream(keystoreFile); char[] pw = password == null ? new char[0] : password.toCharArray(); keystore.load(keystoreInputStream, pw); keystoreInputStream.close(); privateKeyEntry = (PrivateKeyEntry) keystore.getEntry(alias, new KeyStore.PasswordProtection(pw)); } catch (Exception e) { error( "No able to load the private key from the give keystore(" + keystoreFile.getAbsolutePath() + ") with alias " + alias + " : " + e); return; } finally { IO.close(keystoreInputStream); } PrivateKey privateKey = privateKeyEntry.getPrivateKey(); Signature signature = Signature.getInstance("MD5withRSA"); signature.initSign(privateKey); signature.update(signatureFileBytes); signature.sign(); // TODO, place the SF in a PCKS#7 structure ... // no standard class for this? The following // is an idea but we will to have do ASN.1 BER // encoding ... ByteArrayOutputStream tmpStream = new ByteArrayOutputStream(); jar.putResource("META-INF/BND.RSA", new EmbeddedResource(tmpStream.toByteArray(), 0)); } catch (Exception e) { error("During signing: " + e); } }
public CommandData parseCommandData(ArtifactData artifact) throws Exception { File source = new File(artifact.file); if (!source.isFile()) throw new FileNotFoundException(); CommandData data = new CommandData(); data.sha = artifact.sha; data.jpmRepoDir = repoDir.getCanonicalPath(); JarFile jar = new JarFile(source); try { reporter.trace("Parsing %s", source); Manifest m = jar.getManifest(); Attributes main = m.getMainAttributes(); data.name = data.bsn = main.getValue("Bundle-SymbolicName"); String version = main.getValue("Bundle-Version"); if (version == null) data.version = Version.LOWEST; else data.version = new Version(version); data.main = main.getValue("Main-Class"); data.description = main.getValue("Bundle-Description"); data.title = main.getValue("JPM-Name"); reporter.trace("name " + data.name + " " + data.main + " " + data.title); DependencyCollector path = new DependencyCollector(this); path.add(artifact); DependencyCollector bundles = new DependencyCollector(this); if (main.getValue("JPM-Classpath") != null) { Parameters requires = OSGiHeader.parseHeader(main.getValue("JPM-Classpath")); for (Map.Entry<String, Attrs> e : requires.entrySet()) { path.add(e.getKey(), e.getValue().get("name")); // coordinate } } else if (!artifact.local) { // No JPM-Classpath, falling back to // server's revision // Iterable<RevisionRef> closure = // library.getClosure(artifact.sha, // false); // System.out.println("getting closure " + artifact.url + " " + // Strings.join("\n",closure)); // if (closure != null) { // for (RevisionRef ref : closure) { // path.add(Hex.toHexString(ref.revision)); // } // } } if (main.getValue("JPM-Runbundles") != null) { Parameters jpmrunbundles = OSGiHeader.parseHeader(main.getValue("JPM-Runbundles")); for (Map.Entry<String, Attrs> e : jpmrunbundles.entrySet()) { bundles.add(e.getKey(), e.getValue().get("name")); } } reporter.trace("collect digests runpath"); data.dependencies.addAll(path.getDigests()); reporter.trace("collect digests bundles"); data.runbundles.addAll(bundles.getDigests()); Parameters command = OSGiHeader.parseHeader(main.getValue("JPM-Command")); if (command.size() > 1) reporter.error("Only one command can be specified"); for (Map.Entry<String, Attrs> e : command.entrySet()) { data.name = e.getKey(); Attrs attrs = e.getValue(); if (attrs.containsKey("jvmargs")) data.jvmArgs = attrs.get("jvmargs"); if (attrs.containsKey("title")) data.title = attrs.get("title"); if (data.title != null) data.title = data.name; } return data; } finally { jar.close(); } }