private void doVerify(Jar dot) throws Exception { Verifier verifier = new Verifier(dot, getProperties()); verifier.setPedantic(isPedantic()); // Give the verifier the benefit of our analysis // prevents parsing the files twice verifier.setClassSpace(classspace, contained, referred, uses); verifier.verify(); getInfo(verifier); }
public void verify() throws IOException { if (classSpace == null) classSpace = analyzeBundleClasspath(dot, parseHeader(getHeader(Analyzer.BUNDLE_CLASSPATH)), contained, referred, uses); verifyManifestFirst(); verifyActivator(); verifyActivationPolicy(); verifyComponent(); verifyNative(); verifyInvalidExports(); verifyInvalidImports(); verifyUnresolvedReferences(); verifySymbolicName(); verifyListHeader("Bundle-RequiredExecutionEnvironment", EENAME, false); verifyHeader("Bundle-ManifestVersion", BUNDLEMANIFESTVERSION, false); verifyHeader("Bundle-Version", VERSION, true); verifyListHeader("Bundle-Classpath", FILE, false); verifyDynamicImportPackage(); verifyBundleClasspath(); if (usesRequire) { if (!getErrors().isEmpty()) { getWarnings() .add( 0, "Bundle uses Require Bundle, this can generate false errors because then not enough information is available without the required bundles"); } } }
public boolean verifyActivationPolicy() { String policy = getHeader(Constants.BUNDLE_ACTIVATIONPOLICY); if (policy == null) return true; return verifyActivationPolicy(policy); }
public boolean verifyFilter(String value) { try { verifyFilter(value, 0); return true; } catch (Exception e) { error("Not a valid filter: " + value + e.getMessage()); return false; } }
try { Jar jar = new Jar(mf.getName(), mf); Verifier verifier = new Verifier(jar); try { verifier.verify(); if (verifier.getErrors().size() + verifier.getWarnings().size() > 0) { List<String> info = new ArrayList<String>(verifier.getErrors()); info.addAll(verifier.getWarnings()); Activator.getDefault().error(info); verifier.close();
private List<Jar> getBundleClassPath() { List<Jar> list = newList(); String bcp = getHeader(Analyzer.BUNDLE_CLASSPATH); if (bcp == null) { list.add(dot); } else { Map<String, Map<String, String>> entries = parseHeader(bcp); for (String jarOrDir : entries.keySet()) { if (jarOrDir.equals(".")) { jarOrDir = ""; if (jarOrDir.endsWith("/")) { error("Bundle-Classpath directory must not end with a slash: " + jarOrDir); jarOrDir = jarOrDir.substring(0, jarOrDir.length() - 1); try { Jar sub = new Jar(jarOrDir); addClose(sub); EmbeddedResource.build(sub, resource); if (!jarOrDir.endsWith(".jar")) warning("Valid JAR file on Bundle-Classpath does not have .jar extension: " + jarOrDir); list.add(sub); } catch (Exception e) { error("Invalid embedded JAR file on Bundle-Classpath: " + jarOrDir + ", " + e); error("R3 bundles do not support directories on the Bundle-ClassPath: " + jarOrDir);
public Verifier(Jar jar, Properties properties) throws Exception { this.dot = jar; this.properties = properties; this.manifest = jar.getManifest(); if (manifest == null) { manifest = new Manifest(); error("This file contains no manifest and is therefore not a bundle"); } main = this.manifest.getMainAttributes(); verifyHeaders(main); r3 = getHeader(Analyzer.BUNDLE_MANIFESTVERSION) == null; usesRequire = getHeader(Analyzer.REQUIRE_BUNDLE) != null; fragment = getHeader(Analyzer.FRAGMENT_HOST) != null; bundleClasspath = getBundleClassPath(); mimports = parseHeader(manifest.getMainAttributes().getValue( Analyzer.IMPORT_PACKAGE)); mdynimports = parseHeader(manifest.getMainAttributes().getValue( Analyzer.DYNAMICIMPORT_PACKAGE)); mexports = parseHeader(manifest.getMainAttributes().getValue( Analyzer.EXPORT_PACKAGE)); ignore = parseHeader(manifest.getMainAttributes().getValue( Analyzer.IGNORE_PACKAGE)); }
verifyListHeader("DynamicImport-Package", WILDCARDPACKAGE, true); String dynamicImportPackage = getHeader("DynamicImport-Package"); if (dynamicImportPackage == null) return; Map<String, Map<String, String>> map = parseHeader(dynamicImportPackage); for (String name : map.keySet()) { name = name.trim(); if (!verify(name, WILDCARDPACKAGE)) error("DynamicImport-Package header contains an invalid package name: " + name); error("DynamicPackage-Import has attributes on import: " + name + ". This is however, an <=R3 bundle and attributes on this header were introduced in R4. ");
/** * Invalid imports are imports that we never refer to. They can be * calculated by removing the refered packages from the imported packages. * This leaves packages that the manifest imported but that we never use. */ private void verifyInvalidImports() { Set<String> invalidImport = newSet(mimports.keySet()); invalidImport.removeAll(referred.keySet()); // TODO Added this line but not sure why it worked before ... invalidImport.removeAll(contained.keySet()); String bactivator = getHeader(Analyzer.BUNDLE_ACTIVATOR); if (bactivator != null) { int n = bactivator.lastIndexOf('.'); if (n > 0) { invalidImport.remove(bactivator.substring(0, n)); } } if (isPedantic() && !invalidImport.isEmpty()) warning("Importing packages that are never refered to by any class on the Bundle-Classpath" + bundleClasspath + ": " + invalidImport); }
String name = qt.nextToken(); if (name == null) { error("Can not parse name from bundle native code header: " + nc); return; if (del == ';') { if (dot != null && !dot.exists(name)) { error("Native library not found in JAR: " + name); verify(value, VERSIONRANGE); } else if (key.equals("language")) { verify(value, ISO639); } else if (key.equals("processor")) { verifyFilter(value); } else if (name.equals("*") && value == null) { error("Bundle-Native code header may only END in wildcard: nc"); } else { warning("Unknown attribute in native code: " + name + "=" + value);
private void verifySymbolicName() { Map<String, Map<String, String>> bsn = parseHeader(getHeader(Analyzer.BUNDLE_SYMBOLICNAME)); if (!bsn.isEmpty()) { if (bsn.size() > 1) error("More than one BSN specified " + bsn); String name = (String) bsn.keySet().iterator().next(); if (!SYMBOLICNAME.matcher(name).matches()) { error("Symbolic Name has invalid format: " + name); } } }
public void verifyBundleClasspath() { Map<String, Map<String, String>> bcp = parseHeader(getHeader(Analyzer.BUNDLE_CLASSPATH)); if (bcp.isEmpty() || bcp.containsKey(".")) return; for ( String path : bcp.keySet() ) { if ( path.endsWith("/")) error("A Bundle-ClassPath entry must not end with '/': %s", path); if ( dot.getDirectories().containsKey(path)) // We assume that any classes are in a directory // and therefore do not care when the bundle is included return; } for (String path : dot.getResources().keySet()) { if (path.endsWith(".class")) { warning("The Bundle-Classpath does not contain the actual bundle JAR (as specified with '.' in the Bundle-Classpath) but the JAR does contain classes. Is this intentional?"); return; } } }
private void verifySymbolicName() { Map<String, Map<String, String>> bsn = parseHeader(getHeader(Analyzer.BUNDLE_SYMBOLICNAME)); if (!bsn.isEmpty()) { if (bsn.size() > 1) error("More than one BSN specified " + bsn); String name = (String) bsn.keySet().iterator().next(); if (!isBsn(name)) { error("Symbolic Name has invalid format: " + name); } } }
public void submit(Jar jar) throws Exception { String host = getProperty("libsync.repo", "http://libsync.com/repo"); try { URL url = new URL(host); Verifier v = new Verifier(jar); v.setPedantic(true); v.verify(); getInfo(v); if (isOk() && v.getWarnings().isEmpty()) { send0(jar, url); } } catch (MalformedURLException e) { error("The libsync.repo property does not contain a proper URL %s, exception: %s", host, e); } catch (Exception e) { error("Submission of %s to %s failed even after retrying", host, jar.getName()); } }
private boolean verifyListHeader(String name, Pattern regex, boolean error) { String value = manifest.getMainAttributes().getValue(name); if (value == null) return false; Map<String, Map<String, String>> map = parseHeader(value); for (String header : map.keySet()) { if (!regex.matcher(header).matches()) { String msg = "Invalid value for " + name + ", " + value + " does not match " + regex.pattern(); if (error) error(msg); else warning(msg); } } return true; }
private boolean verifyHeader(String name, Pattern regex, boolean error) { String value = manifest.getMainAttributes().getValue(name); if (value == null) return false; QuotedTokenizer st = new QuotedTokenizer(value.trim(), ","); for (Iterator<String> i = st.getTokenSet().iterator(); i.hasNext();) { if (!verify((String) i.next(), regex)) { String msg = "Invalid value for " + name + ", " + value + " does not match " + regex.pattern(); if (error) error(msg); else warning(msg); } } return true; }
private void verifyActivator() { String bactivator = getHeader("Bundle-Activator"); if (bactivator != null) { Clazz cl = loadClass(bactivator); if (cl == null) { int n = bactivator.lastIndexOf('.'); if (n > 0) { String pack = bactivator.substring(0, n); if (mimports.containsKey(pack)) return; error("Bundle-Activator not found on the bundle class path nor in imports: " + bactivator); } else error("Activator uses default package and is not local (default package can not be imported): " + bactivator); } } }
/** * Invalid exports are exports mentioned in the manifest but not found on * the classpath. This can be calculated with: exports - contains. * * Unfortunately, we also must take duplicate names into account. These * duplicates are of course no erroneous. */ private void verifyInvalidExports() { Set<String> invalidExport = newSet(mexports.keySet()); invalidExport.removeAll(contained.keySet()); // We might have duplicate names that are marked for it. These // should not be counted. Should we test them against the contained // set? Hmm. If someone wants to hang himself by using duplicates than // I guess he can go ahead ... This is not a recommended practice for (Iterator<String> i = invalidExport.iterator(); i.hasNext();) { String pack = i.next(); if (isDuplicate(pack)) i.remove(); } if (!invalidExport.isEmpty()) error("Exporting packages that are not on the Bundle-Classpath" + bundleClasspath + ": " + invalidExport); }
else { if (isDynamicImport(pack)) p.remove(); if (hasOverlap(unresolvedReferences, clazz.imports.keySet())) culprits.add(clazz.getPath()); error("Unresolved references to " + unresolvedReferences + " by class(es) on the Bundle-Classpath" + bundleClasspath + ": " + culprits);