• Intro Headers Instructions Macros Commands
  • Fork me on GitHub
    • Introduction
    • How to install bnd
    • Guided Tour
    • Guided Tour Workspace & Projects
    • Concepts
    • Best practices
    • Build
    • Project Setup
    • Generating JARs
    • Versioning
    • Baselining
    • Service Components
    • Metatype
    • Contracts
    • Bundle Annotations
    • Accessor Properties
    • SPI Annotations
    • Resolving Dependencies
    • Launching
    • Startlevels
    • Testing
    • Testing with Launchpad
    • Packaging Applications
    • JPMS Libraries
    • Wrapping Libraries to OSGi Bundles
    • Generating Documentation
    • Commands
    • For Developers
    • Tips for Windows users
    • Tools bound to bnd
    • Headers
    • Instruction Reference
    • Instruction Index
    • Macro Reference
    • Macro Index
    • Plugins
    • External Plugins
    • Settings
    • Errors
    • Warnings
    • Frequently Asked Questions
  • Bundle-ClassPath ::= entry ( ',' entry )*

    Defines the internal bundle class path, is taken into accont by bnd. That is, classes will be analyzed according to this path. The files/directories on the Bundle-ClassPath must be present in the bundle. Use Include-Resource to include these jars/directories in your bundle. In general you should not use Bundle-ClassPath since it makes things more complicated than necessary. Use the @ option in the Include-Resource to unroll the jars into the JAR.

    public void verifyBundleClasspath() {
    	Parameters bcp = main.getBundleClassPath();
    	if (bcp.isEmpty() || bcp.containsKey("."))
    		return;
    
    	for (String path : bcp.keySet()) {
    		if (path.endsWith("/"))
    			error("A " + Constants.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 " + Constants.BUNDLE_CLASSPATH + " does not contain the actual bundle JAR (as specified with '.' in the " + Constants.BUNDLE_CLASSPATH + ") but the JAR does contain classes. Is this intentional?");
    			return;
    		}
    	}
    }
    
    
    
    
    	/**
     * Check for unresolved imports. These are referrals that are not imported
     * by the manifest and that are not part of our bundle class path. The are
     * calculated by removing all the imported packages and contained from the
     * referred packages.
     * @throws Exception 
     */
    private void verifyUnresolvedReferences() throws Exception {
    
    	//
    	// If we're being called from the builder then this should
    	// already have been done
    	//
    
    	if (isFrombuilder())
    		return;
    
    	Manifest m = analyzer.getJar().getManifest();
    	if (m == null) {
    		error("No manifest");
    	}
    
    	Domain domain = Domain.domain(m);
    	
    	Set<PackageRef> unresolvedReferences = new TreeSet<PackageRef>(analyzer.getReferred().keySet());
    	unresolvedReferences.removeAll(analyzer.getContained().keySet());
    	for ( String pname : domain.getImportPackage().keySet()) {
    		PackageRef pref = analyzer.getPackageRef(pname);
    		unresolvedReferences.remove(pref);
    	}
    
    	// Remove any java.** packages.
    	for (Iterator<PackageRef> p = unresolvedReferences.iterator(); p.hasNext();) {
    		PackageRef pack = p.next();
    		if (pack.isJava())
    			p.remove();
    		else {
    			// Remove any dynamic imports
    			if (isDynamicImport(pack))
    				p.remove();
    		}
    	}
    
    	//
    	// If there is a Require bundle, all bets are off and
    	// we cannot verify anything
    	//
    
    	if (domain.getRequireBundle().isEmpty() && domain.get("ExtensionBundle-Activator") == null
    			&& (domain.getFragmentHost()== null || domain.getFragmentHost().getKey().equals("system.bundle"))) {
    
    		if (!unresolvedReferences.isEmpty()) {
    			// Now we want to know the
    			// classes that are the culprits
    			Set<String> culprits = new HashSet<String>();
    			for (Clazz clazz : analyzer.getClassspace().values()) {
    				if (hasOverlap(unresolvedReferences, clazz.getReferred()))
    					culprits.add(clazz.getAbsolutePath());
    			}
    
    			if (analyzer instanceof Builder)
    				warning("Unresolved references to %s by class(es) %s on the " + Constants.BUNDLE_CLASSPATH + ": %s",
    						unresolvedReferences, culprits, analyzer.getBundleClasspath().keySet());
    			else
    				error("Unresolved references to %s by class(es) %s on the " + Constants.BUNDLE_CLASSPATH + ": %s",
    						unresolvedReferences, culprits, analyzer.getBundleClasspath().keySet());
    			return;
    		}
    	} else if (isPedantic())
    		warning("Use of " + Constants.REQUIRE_BUNDLE + ", ExtensionBundle-Activator, or a system bundle fragment makes it impossible to verify unresolved references");
    }
    
    
    
    
    					if (dot.getDirectories().containsKey(path)) {
    					// if directories are used, we should not have dot as we
    					// would have the classes in these directories on the
    					// class path twice.
    					if (bcp.containsKey("."))
    						warning(Constants.BUNDLE_CLASSPATH
    								+ " uses a directory '%s' as well as '.'. This means bnd does not know if a directory is a package.",
    								path, path);
    					analyzeJar(dot, Processor.appendPath(path) + "/", true);
    				} else {
    					if (!"optional".equals(info.get(RESOLUTION_DIRECTIVE)))
    						warning("No sub JAR or directory " + path);
    				}
    
    
    			Parameters bcp = getBundleClasspath();
    		if (bcp.isEmpty() || (bcp.containsKey(".") && bcp.size() == 1))
    			main.remove(BUNDLE_CLASSPATH);
    		else
    			main.putValue(BUNDLE_CLASSPATH, printClauses(bcp));
    
    		// ----- Require/Capabilities section
    
    • GitHub