예제 #1
0
  /** 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")));
    }
  }
  /**
   * All the BND magic happens here.
   *
   * @param jarInputStream On what to operate.
   * @param instructions BND instructions from user API
   * @param symbolicName Mandatory Header. In case user does not set it.
   * @return Bundle Jar Stream
   * @throws Exception Problems go here
   */
  private InputStream createBundle(
      InputStream jarInputStream, Properties instructions, String symbolicName) throws Exception {
    NullArgumentException.validateNotNull(jarInputStream, "Jar URL");
    NullArgumentException.validateNotNull(instructions, "Instructions");
    NullArgumentException.validateNotEmpty(symbolicName, "Jar info");

    final Jar jar = new Jar("dot", sink(jarInputStream));

    final Properties properties = new Properties();
    properties.putAll(instructions);

    final Analyzer analyzer = new Analyzer();
    analyzer.setJar(jar);
    analyzer.setProperties(properties);

    // throw away already existing headers that we overwrite:

    analyzer.mergeManifest(jar.getManifest());

    checkMandatoryProperties(analyzer, jar, symbolicName);
    Manifest manifest = analyzer.calcManifest();
    jar.setManifest(manifest);

    return createInputStream(jar);
  }
예제 #3
0
  /**
   * Test if we can select
   *
   * @throws Exception
   */
  public void testSelect() throws Exception {
    Jar bjara = getContractExporter("atest", "2.5", "${exports}");
    Jar bjarb = getContractExporter("btest", "2.5", "${exports}");

    Builder a = newBuilder();
    a.setTrace(true);

    a.addClasspath(bjara); // 1x
    a.addClasspath(bjarb); // 2x
    a.setProperty(Constants.CONTRACT, "atest;alpha=1");
    a.setImportPackage("org.osgi.service.cm,*");
    a.setProperty("Export-Package", "test.refer");
    Jar ajar = a.build();
    assertTrue(a.check());
    ajar.getManifest().write(System.out);

    Domain domain = Domain.domain(ajar.getManifest());
    Parameters p = domain.getRequireCapability();
    p.remove("osgi.ee");
    assertNotNull(p);
    assertEquals(1, p.size());
    Attrs attrs = p.get("osgi.contract");
    String alpha = attrs.get("alpha");
    assertEquals("1", alpha);
    assertEquals("(&(osgi.contract=atest)(version=2.5.0))", attrs.get("filter:"));
  }
예제 #4
0
  private void copy(File workspaceDir, InputStream in, Pattern glob, boolean overwrite)
      throws Exception {

    Jar jar = new Jar("dot", in);
    try {
      for (Entry<String, Resource> e : jar.getResources().entrySet()) {

        String path = e.getKey();
        bnd.trace("path %s", path);

        if (glob != null && !glob.matcher(path).matches()) continue;

        Resource r = e.getValue();
        File dest = Processor.getFile(workspaceDir, path);
        if (overwrite
            || !dest.isFile()
            || dest.lastModified() < r.lastModified()
            || r.lastModified() <= 0) {

          bnd.trace("copy %s to %s", path, dest);

          File dp = dest.getParentFile();
          if (!dp.exists() && !dp.mkdirs()) {
            throw new IOException("Could not create directory " + dp);
          }

          IO.copy(r.openInputStream(), dest);
        }
      }
    } finally {
      jar.close();
    }
  }
예제 #5
0
  /** @throws Exception */
  File[] getBundleClasspathFiles() throws Exception {

    if (this.bundleClasspathExpansion != null) return bundleClasspathExpansion;

    File file = getFile();

    Manifest m = getManifest();
    String bundleClassPath;
    if (m == null
        || (bundleClassPath = m.getMainAttributes().getValue(Constants.BUNDLE_CLASSPATH)) == null) {
      this.bundleClasspathExpansion = new File[] {file};
    } else {

      File bundleClasspathDirectory =
          IO.getFile(file.getParentFile(), "." + file.getName() + "-bcp");
      Parameters header = new Parameters(bundleClassPath);
      this.bundleClasspathExpansion = new File[header.size()];
      bundleClasspathDirectory.mkdir();

      int n = 0;
      Jar jar = null;
      try {
        for (Map.Entry<String, Attrs> entry : header.entrySet()) {
          if (".".equals(entry.getKey())) {
            this.bundleClasspathExpansion[n] = file;
          } else {
            File member = new File(bundleClasspathDirectory, n + "-" + toName(entry.getKey()));
            if (!isCurrent(file, member)) {

              if (jar == null) {
                jar = new Jar(file);
              }

              Resource resource = jar.getResource(entry.getKey());
              if (resource == null) {
                warning += "Invalid bcp entry: " + entry.getKey() + "\n";
              } else {
                IO.copy(resource.openInputStream(), member);
                member.setLastModified(file.lastModified());
              }
            }
            this.bundleClasspathExpansion[n] = member;
          }
          n++;
        }
      } finally {
        if (jar != null) jar.close();
      }
    }

    return this.bundleClasspathExpansion;
  }
예제 #6
0
  public static void testSimple() throws Exception {
    Builder bmaker = new Builder();
    bmaker.addClasspath(IO.getFile("jar/mina.jar"));
    bmaker.set("Export-Package", "org.apache.mina.*;version=1");
    bmaker.set("DynamicImport-Package", "org.slf4j");
    Jar jar = bmaker.build();
    assertTrue(bmaker.check());

    Manifest m = jar.getManifest();
    m.write(System.err);
    assertTrue(m.getMainAttributes().getValue("Import-Package").indexOf("org.slf4j") >= 0);
    assertTrue(m.getMainAttributes().getValue("DynamicImport-Package").indexOf("org.slf4j") >= 0);
  }
예제 #7
0
  /** 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"));
  }
예제 #8
0
  /**
   * Verify that the Meta-Persistence header is correctly verified
   *
   * @throws Exception
   */
  public void verifyMetaPersistence() throws Exception {
    Builder b = new Builder();
    b.setIncludeResource("foo.xml;literal='I exist'");
    Jar inner = b.build();
    assertTrue(b.check());

    Jar outer = new Jar("x");
    outer.putResource("foo.jar", new JarResource(inner));
    Manifest m = new Manifest();
    m.getMainAttributes()
        .putValue(Constants.META_PERSISTENCE, "foo.jar, foo.jar!/foo.xml, absent.xml");
    outer.setManifest(m);
    Verifier v = new Verifier(outer);
    v.verifyMetaPersistence();
    assertTrue(v.check("Meta-Persistence refers to resources not in the bundle: \\[absent.xml\\]"));
  }
예제 #9
0
  /** 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));
  }
예제 #10
0
  /**
   * 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"));
  }
예제 #11
0
  /**
   * 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"));
  }
예제 #12
0
  private File create(String bsn, Version v) throws Exception {
    String name = bsn + "-" + v;
    Builder b = new Builder();
    b.setBundleSymbolicName(bsn);
    b.setBundleVersion(v);
    b.setProperty("Random", random++ + "");
    b.setProperty("-resourceonly", true + "");
    b.setIncludeResource("foo;literal='foo'");
    Jar jar = b.build();
    assertTrue(b.check());

    File file = IO.getFile(tmp, name + ".jar");
    file.getParentFile().mkdirs();
    jar.updateModified(System.currentTimeMillis(), "Force it to now");
    jar.write(file);
    b.close();
    return file;
  }
예제 #13
0
  /**
   * Make sure we do not add a contract if not used
   *
   * @throws Exception
   */
  public void testUnused() throws Exception {
    Jar bjara = getContractExporter("atest", "2.5", "${exports}");

    Builder a = newBuilder();
    a.setTrace(true);
    a.addClasspath(bjara);

    a.setProperty(Constants.CONTRACT, "*");
    a.setImportPackage("test.packageinfo,*");
    a.setProperty("Export-Package", "test.refer");
    Jar ajar = a.build();
    assertTrue(a.check());

    Domain domain = Domain.domain(ajar.getManifest());
    Parameters p = domain.getRequireCapability();
    p.remove("osgi.ee");
    assertEquals(0, p.size());
  }
  /** Created a JAR that is a bundle and that contains its dependencies */
  @Override
  public Jar executable() throws Exception {
    Collection<String> bsns = getProject().getBsns();
    if (bsns.size() != 1)
      throw new IllegalArgumentException(
          "Can only handle a single bsn for a run configuration " + bsns);
    String bsn = bsns.iterator().next();

    Jar jar = new Jar(bsn);
    String path = "aQute/remote/embedded/activator/EmbeddedActivator.class";
    URLResource resource = new URLResource(getClass().getClassLoader().getResource(path));
    jar.putResource("aQute/remote/embedded/activator/EmbeddedActivator.class", resource);

    Collection<Container> rb = getProject().getRunbundles();
    rb = Container.flatten(rb);
    Attrs attrs = new Attrs();

    for (Container c : rb) {
      if (c.getError() != null) {
        getProject().error("invalid runbundle %s", c);
      } else {
        File f = c.getFile();
        String tbsn = c.getBundleSymbolicName();
        String version = c.getVersion();
        if (version == null || !Version.isVersion(version))
          getProject()
              .warning("The version of embedded bundle %s does not have a proper version", c);

        jar.putResource("jar/" + c.getBundleSymbolicName() + ".jar", new FileResource(f));

        attrs.put(tbsn, version);
      }
    }

    Analyzer a = new Analyzer(getProject());
    a.setJar(jar);

    a.setBundleActivator(EmbeddedActivator.class.getName());
    a.setProperty("Bnd-Embedded", attrs.toString().replace(';', ','));
    Manifest manifest = a.calcManifest();
    jar.setManifest(manifest);
    getProject().getInfo(a);
    return jar;
  }
예제 #15
0
  @SuppressWarnings("deprecation")
  private void tryJMXDeploy(String jmx, String bsn) {
    JMXBundleDeployer jmxBundleDeployer = null;
    int port = -1;

    try {
      port = Integer.parseInt(jmx);
    } catch (Exception e) {
      // not an integer
    }

    try {
      if (port > -1) {
        jmxBundleDeployer = new JMXBundleDeployer(port);
      } else {
        jmxBundleDeployer = new JMXBundleDeployer();
      }
    } catch (Exception e) {
      // ignore if we can't create bundle deployer (no remote osgi.core
      // jmx avail)
    }

    if (jmxBundleDeployer != null) {
      for (String path : this.getRunpath()) {
        File file = new File(path);
        try {
          Jar jar = new Jar(file);
          try {
            if (bsn.equals(jar.getBsn())) {
              long bundleId = jmxBundleDeployer.deploy(bsn, file);

              trace("agent installed with bundleId=%s", bundleId);
              break;
            }
          } finally {
            jar.close();
          }
        } catch (Exception e) {
          //
        }
      }
    }
  }
예제 #16
0
  /**
   * 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"));
  }
예제 #17
0
  /**
   * Test the warnings that we have no no version
   *
   * @throws Exception
   */
  public void testWarningVersion() throws Exception {
    Jar bjara = getContractExporter("abc", null, "${exports}");

    Builder a = newBuilder();
    a.setTrace(true);
    a.addClasspath(bjara);

    a.setProperty(Constants.CONTRACT, "*");
    a.setImportPackage("test.packageinfo,*");
    a.setProperty("Export-Package", "test.refer");
    Jar ajar = a.build();
    assertTrue(
        a.check(
            "Contract \\[name=abc;version=0.0.0;from=biz.aQute.bndlib.tests] does not declare a version"));

    Domain domain = Domain.domain(ajar.getManifest());
    Parameters p = domain.getRequireCapability();
    p.remove("osgi.ee");
    assertEquals(0, p.size());
  }
예제 #18
0
  public void testSimple() throws Exception {
    Jar bjar = getContractExporter("test", "2.5", "${exports}");

    Builder a = newBuilder();
    a.setTrace(true);
    a.addClasspath(bjar);
    a.setProperty(Constants.CONTRACT, "*");
    a.setImportPackage("org.osgi.service.cm,*");
    a.setProperty("Export-Package", "test.refer");
    Jar ajar = a.build();
    assertTrue(a.check());
    Domain domain = Domain.domain(ajar.getManifest());
    Parameters rc = domain.getRequireCapability();
    rc.remove("osgi.ee");
    System.out.println(rc);
    assertEquals(1, rc.size());

    Packages ps = a.getImports();
    assertTrue(ps.containsFQN("org.osgi.service.cm"));
    Attrs attrs = ps.getByFQN("org.osgi.service.cm");
    assertNotNull(attrs);
    assertNull(attrs.getVersion());
  }
예제 #19
0
  private static String getLatestRemoteBladeCLIJar() {
    _settingsDir.mkdirs();
    repoCache.mkdirs();

    Processor reporter = new Processor();
    FixedIndexedRepo repo = new FixedIndexedRepo();
    Map<String, String> props = new HashMap<String, String>();
    props.put("name", "index1");
    props.put("locations", getRepoURL() + "index.xml.gz");
    props.put(FixedIndexedRepo.PROP_CACHE, repoCache.getAbsolutePath());

    repo.setProperties(props);
    repo.setReporter(reporter);

    try {
      File[] files = repo.get("com.liferay.blade.cli", "[2,3)");

      File cliJar = files[0];

      try (Jar cliJarJar = new Jar(cliJar);
          Jar localJar = new Jar(getLocalCopy())) {
        Version cliJarVersion = new Version(cliJarJar.getVersion());
        Version localCopyVersion = new Version(localJar.getVersion());

        if (cliJarVersion.compareTo(localCopyVersion) >= 0) {
          cachedBladeCLIPath = new Path(cliJar.getCanonicalPath());
        } else {
          return null;
        }
      }

      return cliJar.getName();
    } catch (Exception e) {
      return null;
    }
  }
예제 #20
0
  /**
   * 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"));
  }
  private String _calculateExportPackage(Jar jar) {
    StringBundler sb = new StringBundler();

    String delimiter = StringPool.BLANK;

    Map<String, Map<String, Resource>> directories = jar.getDirectories();

    for (String directory : directories.keySet()) {
      if (directory.equals("META-INF") || directory.startsWith("META-INF/")) {

        continue;
      }

      if (directory.equals("OSGI-OPT") || directory.startsWith("OSGI-OPT/")) {

        continue;
      }

      if (directory.equals(StringPool.SLASH)) {
        continue;
      }

      if (directory.endsWith(StringPool.SLASH)) {
        directory = directory.substring(0, directory.length() - 1);
      }

      if (directory.endsWith(StringPool.SLASH)) {
        directory = directory.substring(0, directory.length() - 1);
      }

      String className = directory.replace(StringPool.SLASH, StringPool.PERIOD);

      if (directories.get(directory) != null) {
        sb.append(delimiter);
        sb.append(className);

        delimiter = StringPool.COMMA;
      }
    }

    return sb.toString();
  }
예제 #22
0
파일: Signer.java 프로젝트: JSlain/bnd
  private void doManifest(
      Jar jar, String[] digestNames, MessageDigest[] algorithms, OutputStream out)
      throws Exception {

    for (Map.Entry<String, Resource> entry : jar.getResources().entrySet()) {
      String name = entry.getKey();
      if (!METAINFDIR.matcher(name).matches()) {
        out.write("\r\n".getBytes("UTF-8"));
        out.write("Name: ".getBytes("UTF-8"));
        out.write(name.getBytes("UTF-8"));
        out.write("\r\n".getBytes("UTF-8"));

        digest(algorithms, entry.getValue());
        for (int a = 0; a < algorithms.length; a++) {
          if (algorithms[a] != null) {
            byte[] digest = algorithms[a].digest();
            String header = digestNames[a] + "-Digest: " + new Base64(digest) + "\r\n";
            out.write(header.getBytes("UTF-8"));
          }
        }
      }
    }
  }
예제 #23
0
  @SuppressWarnings("cast")
  private void executeBackwardCompatible() throws BuildException {
    try {
      if (files == null) throw new BuildException("No files set");

      if (eclipse) {
        File project = getProject().getBaseDir();
        EclipseClasspath cp = new EclipseClasspath(this, project.getParentFile(), project);
        classpath.addAll(cp.getClasspath());
        classpath.addAll(cp.getBootclasspath());
        sourcepath.addAll(cp.getSourcepath());
        // classpath.add(cp.getOutput());
        if (report()) throw new BuildException("Errors during Eclipse Path inspection");
      }

      if (output == null) output = getProject().getBaseDir();

      for (Iterator<File> f = files.iterator(); f.hasNext(); ) {
        File file = f.next();
        Builder builder = new Builder();

        builder.setPedantic(isPedantic());
        if (file.exists()) {
          // Do nice property calculations
          // merging includes etc.
          builder.setProperties(file);
        }

        // get them and merge them with the project
        // properties, if the inherit flag is specified
        if (inherit) {
          Properties projectProperties = new UTF8Properties();
          @SuppressWarnings("unchecked")
          Hashtable<Object, Object> antProps = getProject().getProperties();
          projectProperties.putAll(antProps);
          projectProperties.putAll(builder.getProperties());
          builder.setProperties(projectProperties);
        }

        builder.setClasspath(toFiles(classpath, "classpath"));
        builder.setSourcepath(toFiles(sourcepath, "sourcepath"));
        Jar jars[] = builder.builds();

        // Report both task failures and bnd build failures.
        boolean taskFailed = report();
        boolean bndFailed = report(builder);

        // Fail this build if failure is not ok and either the task
        // failed or the bnd build failed.
        if (!failok && (taskFailed || bndFailed)) {
          throw new BuildException(
              "bnd failed", new org.apache.tools.ant.Location(file.getAbsolutePath()));
        }

        for (int i = 0; i < jars.length; i++) {
          Jar jar = jars[i];
          String bsn = jar.getName();

          File base = file.getParentFile();
          File output = this.output;

          String path = builder.getProperty("-output");

          if (output == null) {
            if (path == null) output = getFile(base, bsn + ".jar");
            else {
              output = getFile(base, path);
            }
          } else if (output.isDirectory()) {
            if (path == null) output = getFile(this.output, bsn + ".jar");
            else output = getFile(this.output, path);
          } else if (output.isFile()) {
            if (files.size() > 1) messages.GotFileNeedDir_(output.getAbsoluteFile());
          }

          String msg = "";
          if (!output.exists() || output.lastModified() <= jar.lastModified()) {
            jar.write(output);
          } else {
            msg = "(not modified)";
          }
          trace("%s (%s) %s %s", jar.getName(), output.getName(), jar.getResources().size(), msg);
          report();
          jar.close();
        }
        builder.close();
      }
    } catch (Exception e) {
      // if (exceptions)
      e.printStackTrace();
      if (!failok) throw new BuildException("Failed to build jar file: ", e);
    }
  }
예제 #24
0
  protected void doBaselineJar(Jar jar, File output, aQute.bnd.build.Project bndProject)
      throws Exception {

    if (_reportLevelIsOff) {
      return;
    }

    ProjectBuilder projectBuilder = new ProjectBuilder(bndProject);

    projectBuilder.setClasspath(_classpathFiles.toArray(new File[_classpathFiles.size()]));
    projectBuilder.setPedantic(isPedantic());
    projectBuilder.setProperties(_file);
    projectBuilder.setSourcepath(new File[] {_sourcePath});

    Jar baselineJar = projectBuilder.getBaselineJar();

    try {
      if (baselineJar == null) {
        bndProject.deploy(output);

        return;
      }

      Baseline baseline = new Baseline(this, _diffPluginImpl);

      Set<Info> infos = baseline.baseline(jar, baselineJar, null);

      if (infos.isEmpty()) {
        return;
      }

      BundleInfo bundleInfo = baseline.getBundleInfo();

      Info[] infosArray = infos.toArray(new Info[infos.size()]);

      Arrays.sort(
          infosArray,
          new Comparator<Info>() {

            @Override
            public int compare(Info info1, Info info2) {
              return info1.packageName.compareTo(info2.packageName);
            }
          });

      for (Info info : infosArray) {
        String warnings = "-";

        Version newerVersion = info.newerVersion;
        Version suggestedVersion = info.suggestedVersion;

        if (suggestedVersion != null) {
          if (newerVersion.compareTo(suggestedVersion) > 0) {
            warnings = "EXCESSIVE VERSION INCREASE";
          } else if (newerVersion.compareTo(suggestedVersion) < 0) {
            warnings = "VERSION INCREASE REQUIRED";
          }
        }

        Diff packageDiff = info.packageDiff;

        Delta delta = packageDiff.getDelta();

        if (delta == Delta.REMOVED) {
          warnings = "PACKAGE REMOVED";
        } else if (delta == Delta.UNCHANGED) {
          boolean newVersionSuggested = false;

          if ((suggestedVersion.getMajor() != newerVersion.getMajor())
              || (suggestedVersion.getMicro() != newerVersion.getMicro())
              || (suggestedVersion.getMinor() != newerVersion.getMinor())) {

            warnings = "VERSION INCREASE SUGGESTED";

            newVersionSuggested = true;
          }

          if (!newVersionSuggested && !info.mismatch) {
            continue;
          }
        }

        if (((_reportLevelIsStandard || _reportOnlyDirtyPackages) && warnings.equals("-"))
            || (_reportOnlyDirtyPackages && (delta == Delta.REMOVED))) {

          continue;
        }

        doInfo(bundleInfo, info, warnings);

        if (_reportLevelIsDiff && (delta != Delta.REMOVED)) {
          doPackageDiff(packageDiff);
        }
      }
    } finally {
      if (baselineJar != null) {
        baselineJar.close();
      }

      if (_printWriter != null) {
        _printWriter.close();
      }

      projectBuilder.close();
    }
  }
예제 #25
0
파일: Signer.java 프로젝트: JSlain/bnd
  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);
    }
  }
  private Manifest _calculateManifest(URL url, Manifest manifest) {
    Analyzer analyzer = new Analyzer();

    Jar jar = null;

    try {
      URLConnection urlConnection = url.openConnection();

      String fileName = url.getFile();

      if (urlConnection instanceof JarURLConnection) {
        JarURLConnection jarURLConnection = (JarURLConnection) urlConnection;

        URL jarFileURL = jarURLConnection.getJarFileURL();

        fileName = jarFileURL.getFile();
      }

      File file = new File(fileName);

      if (!file.exists() || !file.canRead()) {
        return manifest;
      }

      fileName = file.getName();

      analyzer.setJar(new Jar(fileName, file));

      jar = analyzer.getJar();

      String bundleSymbolicName = fileName;

      Matcher matcher = _bundleSymbolicNamePattern.matcher(bundleSymbolicName);

      if (matcher.matches()) {
        bundleSymbolicName = matcher.group(1);
      }

      analyzer.setProperty(Analyzer.BUNDLE_SYMBOLICNAME, bundleSymbolicName);

      String exportPackage = _calculateExportPackage(jar);

      analyzer.setProperty(Analyzer.EXPORT_PACKAGE, exportPackage);

      analyzer.mergeManifest(manifest);

      String bundleVersion = analyzer.getProperty(Analyzer.BUNDLE_VERSION);

      if (bundleVersion != null) {
        bundleVersion = Builder.cleanupVersion(bundleVersion);

        analyzer.setProperty(Analyzer.BUNDLE_VERSION, bundleVersion);
      }

      return analyzer.calcManifest();
    } catch (Exception e) {
      _log.error(e, e);

      return manifest;
    } finally {
      if (jar != null) {
        jar.close();
      }

      analyzer.close();
    }
  }
예제 #27
0
 /*
  * Useful for when exported as folder or unzipped
  */
 void doStart(Jar jar, String fqn) throws UnsupportedEncodingException {
   String nix = "#!/bin/sh\njava -cp . " + fqn + "\n";
   String pc = "java -cp . " + fqn + "\r\n";
   jar.putResource("start", new EmbeddedResource(nix, 0));
   jar.putResource("start.bat", new EmbeddedResource(pc, 0));
 }
예제 #28
0
  /**
   * Create a standalone executable. All entries on the runpath are rolled out into the JAR and the
   * runbundles are copied to a directory in the jar. The launcher will see that it starts in
   * embedded mode and will automatically detect that it should load the bundles from inside. This
   * is drive by the launcher.embedded flag.
   *
   * @throws Exception
   */
  @Override
  public Jar executable() throws Exception {

    // TODO use constants in the future
    Parameters packageHeader = OSGiHeader.parseHeader(project.getProperty("-package"));
    boolean useShas = packageHeader.containsKey("jpm");
    project.trace("Useshas %s %s", useShas, packageHeader);

    Jar jar = new Jar(project.getName());

    Builder b = new Builder();
    project.addClose(b);

    if (!project.getIncludeResource().isEmpty()) {
      b.setIncludeResource(project.getIncludeResource().toString());
      b.setProperty(Constants.RESOURCEONLY, "true");
      b.build();
      if (b.isOk()) {
        jar.addAll(b.getJar());
      }
      project.getInfo(b);
    }

    List<String> runpath = getRunpath();

    Set<String> runpathShas = new LinkedHashSet<String>();
    Set<String> runbundleShas = new LinkedHashSet<String>();
    List<String> classpath = new ArrayList<String>();

    for (String path : runpath) {
      project.trace("embedding runpath %s", path);
      File file = new File(path);
      if (file.isFile()) {
        if (useShas) {
          String sha = SHA1.digest(file).asHex();
          runpathShas.add(sha + ";name=\"" + file.getName() + "\"");
        } else {
          String newPath = "jar/" + file.getName();
          jar.putResource(newPath, new FileResource(file));
          classpath.add(newPath);
        }
      }
    }

    // Copy the bundles to the JAR

    List<String> runbundles = (List<String>) getRunBundles();
    List<String> actualPaths = new ArrayList<String>();

    for (String path : runbundles) {
      project.trace("embedding run bundles %s", path);
      File file = new File(path);
      if (!file.isFile()) project.error("Invalid entry in -runbundles %s", file);
      else {
        if (useShas) {
          String sha = SHA1.digest(file).asHex();
          runbundleShas.add(sha + ";name=\"" + file.getName() + "\"");
          actualPaths.add("${JPMREPO}/" + sha);
        } else {
          String newPath = "jar/" + file.getName();
          jar.putResource(newPath, new FileResource(file));
          actualPaths.add(newPath);
        }
      }
    }

    LauncherConstants lc = getConstants(actualPaths, true);
    lc.embedded = !useShas;
    lc.storageDir = null; // cannot use local info

    final Properties p = lc.getProperties(new UTF8Properties());

    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    p.store(bout, "");
    jar.putResource(
        LauncherConstants.DEFAULT_LAUNCHER_PROPERTIES,
        new EmbeddedResource(bout.toByteArray(), 0L));

    Manifest m = new Manifest();
    Attributes main = m.getMainAttributes();

    for (Entry<Object, Object> e : project.getFlattenedProperties().entrySet()) {
      String key = (String) e.getKey();
      if (key.length() > 0 && Character.isUpperCase(key.charAt(0)))
        main.putValue(key, (String) e.getValue());
    }

    Instructions instructions = new Instructions(project.getProperty(Constants.REMOVEHEADERS));
    Collection<Object> result = instructions.select(main.keySet(), false);
    main.keySet().removeAll(result);

    if (useShas) {
      project.trace("Use JPM launcher");
      m.getMainAttributes().putValue("Main-Class", JPM_LAUNCHER_FQN);
      m.getMainAttributes().putValue("JPM-Classpath", Processor.join(runpathShas));
      m.getMainAttributes().putValue("JPM-Runbundles", Processor.join(runbundleShas));
      URLResource jpmLauncher = new URLResource(this.getClass().getResource("/" + JPM_LAUNCHER));
      jar.putResource(JPM_LAUNCHER, jpmLauncher);
      doStart(jar, JPM_LAUNCHER_FQN);
    } else {
      project.trace("Use Embedded launcher");
      m.getMainAttributes().putValue("Main-Class", EMBEDDED_LAUNCHER_FQN);
      m.getMainAttributes().putValue(EmbeddedLauncher.EMBEDDED_RUNPATH, Processor.join(classpath));
      URLResource embeddedLauncher =
          new URLResource(this.getClass().getResource("/" + EMBEDDED_LAUNCHER));
      jar.putResource(EMBEDDED_LAUNCHER, embeddedLauncher);
      doStart(jar, EMBEDDED_LAUNCHER_FQN);
    }
    if (project.getProperty(Constants.DIGESTS) != null)
      jar.setDigestAlgorithms(project.getProperty(Constants.DIGESTS).trim().split("\\s*,\\s*"));
    else jar.setDigestAlgorithms(new String[] {"SHA-1", "MD-5"});
    jar.setManifest(m);
    return jar;
  }
예제 #29
0
파일: JartoolSigner.java 프로젝트: kwin/bnd
  public void sign(Builder builder, String alias) throws Exception {
    File f = builder.getFile(keystore);
    if (!f.isFile()) {
      builder.error("Invalid keystore %s", f.getAbsolutePath());
      return;
    }

    Jar jar = builder.getJar();
    File tmp = File.createTempFile("signdjar", ".jar");
    tmp.deleteOnExit();

    jar.write(tmp);

    Command command = new Command();
    command.add(path);
    if (keystore != null) {
      command.add("-keystore");
      command.add(f.getAbsolutePath());
    }

    if (storetype != null) {
      command.add("-storetype");
      command.add(storetype);
    }

    if (keypass != null) {
      command.add("-keypass");
      command.add(keypass);
    }

    if (storepass != null) {
      command.add("-storepass");
      command.add(storepass);
    }

    if (sigFile != null) {
      command.add("-sigFile");
      command.add(sigFile);
    }

    if (digestalg != null) {
      command.add("-digestalg");
      command.add(digestalg);
    }

    command.add(tmp.getAbsolutePath());
    command.add(alias);
    logger.debug("Jarsigner command: {}", command);
    command.setTimeout(20, TimeUnit.SECONDS);
    StringBuilder out = new StringBuilder();
    StringBuilder err = new StringBuilder();
    int exitValue = command.execute(out, err);
    if (exitValue != 0) {
      builder.error("Signing Jar out: %s%nerr: %s", out, err);
    } else {
      logger.debug("Signing Jar out: {}\nerr: {}", out, err);
    }

    Jar signed = new Jar(tmp);
    builder.addClose(signed);

    Map<String, Resource> dir = signed.getDirectories().get("META-INF");
    for (Entry<String, Resource> entry : dir.entrySet()) {
      String path = entry.getKey();
      if (path.matches(".*\\.(DSA|RSA|SF|MF)$")) {
        jar.putResource(path, entry.getValue());
      }
    }
    jar.setDoNotTouchManifest();
  }
예제 #30
0
  @Override
  protected void doExecute() throws Exception {
    aQute.bnd.build.Project bndProject = getBndProject();

    Builder builder = new Builder(bndProject);

    builder.setClasspath(_classpathFiles.toArray(new File[_classpathFiles.size()]));
    builder.setPedantic(isPedantic());
    builder.setProperties(_file);
    builder.setSourcepath(new File[] {_sourcePath});

    Jar[] jars = builder.builds();

    // Report both task failures and bnd build failures

    boolean taskFailed = report();
    boolean bndFailed = report(builder);

    // Fail this build if failure is not ok and either the task failed or
    // the bnd build failed

    if (taskFailed || bndFailed) {
      throw new BuildException(
          "bnd failed", new org.apache.tools.ant.Location(_file.getAbsolutePath()));
    }

    for (Jar jar : jars) {
      String bsn = jar.getName();

      File outputFile = _outputPath;

      if (_outputPath.isDirectory()) {
        String path = builder.getProperty("-output");

        if (path != null) {
          outputFile = getFile(_outputPath, path);
        } else {
          outputFile = getFile(_outputPath, bsn + ".jar");
        }
      }

      if (!outputFile.exists() || (outputFile.lastModified() <= jar.lastModified())) {

        jar.write(outputFile);

        Map<String, Resource> resources = jar.getResources();

        log(jar.getName() + " (" + outputFile.getName() + ") " + resources.size());

        doBaselineJar(jar, outputFile, bndProject);
      } else {
        Map<String, Resource> resources = jar.getResources();

        log(
            jar.getName()
                + " ("
                + outputFile.getName()
                + ") "
                + resources.size()
                + " (not modified)");
      }

      report();

      jar.close();
    }

    builder.close();
  }