private int readSmbFile(SmbFile f) throws IOException {
   InputStream in = null;
   try {
     in = f.getInputStream();
     return Integer.parseInt(IOUtils.toString(in));
   } finally {
     IOUtils.closeQuietly(in);
   }
 }
Example #2
0
  public synchronized TopLevelItem createProjectFromXML(String name, InputStream xml)
      throws IOException {
    acl.checkPermission(Job.CREATE);

    Jenkins.getInstance().getProjectNamingStrategy().checkName(name);
    // place it as config.xml
    File configXml = Items.getConfigFile(getRootDirFor(name)).getFile();
    configXml.getParentFile().mkdirs();
    try {
      IOUtils.copy(xml, configXml);

      // load it
      TopLevelItem result;
      Items.updatingByXml.set(true);
      try {
        result = (TopLevelItem) Items.load(parent, configXml.getParentFile());
      } finally {
        Items.updatingByXml.set(false);
      }
      add(result);

      ItemListener.fireOnCreated(result);
      Jenkins.getInstance().rebuildDependencyGraph();

      return result;
    } catch (IOException e) {
      // if anything fails, delete the config file to avoid further confusion
      Util.deleteRecursive(configXml.getParentFile());
      throw e;
    }
  }
  @Override
  public void run() {
    ReviewInput reviewInput = createReview();

    String reviewEndpoint = resolveEndpointURL();

    HttpPost httpPost = createHttpPostEntity(reviewInput, reviewEndpoint);

    if (httpPost == null) {
      return;
    }

    DefaultHttpClient httpclient = new DefaultHttpClient();
    httpclient
        .getCredentialsProvider()
        .setCredentials(
            new AuthScope(null, -1),
            new UsernamePasswordCredentials(
                config.getGerritHttpUserName(), config.getGerritHttpPassword()));
    try {
      HttpResponse httpResponse = httpclient.execute(httpPost);
      String response = IOUtils.toString(httpResponse.getEntity().getContent(), "UTF-8");
      listener.getLogger().print(response);
      if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
        listener.error(httpResponse.getStatusLine().getReasonPhrase());
      }
    } catch (Exception e) {
      listener.error("Failed to submit result", e);
    }
  }
 public String generateSlaveXml(String id, String java, String args) throws IOException {
   String xml =
       IOUtils.toString(this.getClass().getResourceAsStream("jenkins-slave.xml"), "UTF-8");
   xml = xml.replace("@ID@", id);
   xml = xml.replace("@JAVA@", java);
   xml = xml.replace("@ARGS@", args);
   return xml;
 }
Example #5
0
 /** Sends out the raw polling log output. */
 public void doPollingLog(StaplerRequest req, StaplerResponse rsp) throws IOException {
   rsp.setContentType("text/plain;charset=UTF-8");
   // Prevent jelly from flushing stream so Content-Length header can be added afterwards
   FlushProofOutputStream out = null;
   try {
     out = new FlushProofOutputStream(rsp.getCompressedOutputStream(req));
     getPollingLogText().writeLogTo(0, out);
   } finally {
     IOUtils.closeQuietly(out);
   }
 }
  /** Skips the encoded console note. */
  public static void skip(DataInputStream in) throws IOException {
    byte[] preamble = new byte[PREAMBLE.length];
    in.readFully(preamble);
    if (!Arrays.equals(preamble, PREAMBLE)) return; // not a valid preamble

    DataInputStream decoded = new DataInputStream(new UnbufferedBase64InputStream(in));
    int sz = decoded.readInt();
    IOUtils.skip(decoded, sz);

    byte[] postamble = new byte[POSTAMBLE.length];
    in.readFully(postamble);
  }
Example #7
0
    /**
     * Accepts <tt>config.xml</tt> submission, as well as serve it.
     */
    @WebMethod(name = "config.xml")
    public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp)
            throws IOException {
        if (req.getMethod().equals("GET")) {
            // read
            checkPermission(EXTENDED_READ);
            rsp.setContentType("application/xml");
            IOUtils.copy(getConfigFile().getFile(),rsp.getOutputStream());
            return;
        }
        if (req.getMethod().equals("POST")) {
            // submission
            updateByXml((Source)new StreamSource(req.getReader()));
            return;
        }

        // huh?
        rsp.sendError(SC_BAD_REQUEST);
    }
Example #8
0
  public void doIndex(StaplerRequest req) throws IOException {
    String payload = IOUtils.toString(req.getReader());
    LOGGER.fine("Full details of the POST was " + payload);

    JSONObject o = JSONObject.fromObject(payload);
    String repoUrl = o.getString("repository_ssl_path");
    LOGGER.info("Received POST for " + repoUrl);

    // run in high privilege to see all the projects anonymous users don't see.
    // this is safe because when we actually schedule a build, it's a build that can
    // happen at some random time anyway.

    // TODO replace with ACL.impersonate as LTS is > 1.461
    Authentication old = SecurityContextHolder.getContext().getAuthentication();
    SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
    try {
      for (AbstractProject<?, ?> job : Jenkins.getInstance().getAllItems(AbstractProject.class)) {
        boolean found = false;
        SCM scm = job.getScm();
        if (scm instanceof SubversionSCM) {
          found = hasRepository(repoUrl, (SubversionSCM) scm);
        } else if (scm instanceof GitSCM) {
          found = hasRepository(repoUrl, (GitSCM) scm);
        } else if (scm instanceof MercurialSCM) {
          found = hasRepository(repoUrl, (MercurialSCM) scm);
        }

        if (found) {
          LOGGER.info(job.getFullDisplayName() + " triggered by web hook.");
          job.scheduleBuild(new WebHookCause());
        }

        LOGGER.fine(
            "Skipped "
                + job.getFullDisplayName()
                + " because it doesn't have a matching repository.");
      }
    } finally {
      SecurityContextHolder.getContext().setAuthentication(old);
    }
  }
  /**
   * Also applicable for workflow jobs.
   *
   * @throws Exception
   */
  @Issue("JENKINS-30357")
  @Test
  public void testWorkflow() throws Exception {
    // Prepare an artifact to be copied.
    FreeStyleProject copiee = j.createFreeStyleProject();
    copiee.getBuildersList().add(new FileWriteBuilder("artifact.txt", "foobar"));
    copiee.getPublishersList().add(new ArtifactArchiver("artifact.txt"));
    j.assertBuildStatusSuccess(copiee.scheduleBuild2(0));

    WorkflowJob copier = createWorkflowJob();
    copier.setDefinition(
        new CpsFlowDefinition(
            String.format(
                "node {"
                    + "step([$class: 'CopyArtifact',"
                    + "projectName: '%1$s',"
                    + "filter: '**/*',"
                    + "selector: [$class: 'ParameterizedBuildSelector', parameterName: 'SELECTOR'],"
                    + "]);"
                    + "step([$class: 'ArtifactArchiver', artifacts: '**/*']);"
                    + "}",
                copiee.getFullName()),
            true));

    WorkflowRun b =
        j.assertBuildStatusSuccess(
            copier.scheduleBuild2(
                0,
                null,
                new ParametersAction(
                    new StringParameterValue(
                        "SELECTOR",
                        "<StatusBuildSelector><stable>true</stable></StatusBuildSelector>"))));

    VirtualFile vf = b.getArtifactManager().root().child("artifact.txt");
    assertEquals("foobar", IOUtils.toString(vf.open()));
  }
Example #10
0
    protected Result doRun(BuildListener listener) throws Exception {
      // pick up a list of reporters to run
      reporters = getProject().createReporters();
      MavenModuleSet mms = getProject().getParent();
      if (debug) listener.getLogger().println("Reporters=" + reporters);

      for (BuildWrapper w : mms.getBuildWrappersList()) {
        Environment e = w.setUp(MavenBuild.this, launcher, listener);
        if (e == null) {
          return Result.FAILURE;
        }
        buildEnvironments.add(e);
      }

      EnvVars envVars = getEnvironment(listener); // buildEnvironments should be set up first

      MavenInstallation mvn = getProject().getParent().getMaven();

      mvn = mvn.forEnvironment(envVars).forNode(Computer.currentComputer().getNode(), listener);

      MavenInformation mavenInformation =
          getModuleRoot().act(new MavenVersionCallable(mvn.getHome()));

      String mavenVersion = mavenInformation.getVersion();

      LOGGER.fine(
          getFullDisplayName()
              + " is building with mavenVersion "
              + mavenVersion
              + " from file "
              + mavenInformation.getVersionResourcePath());

      boolean maven3orLater = MavenUtil.maven3orLater(mavenVersion);

      ProcessCache.MavenProcess process =
          MavenBuild.mavenProcessCache.get(
              launcher.getChannel(),
              listener,
              maven3orLater
                  ? new Maven3ProcessFactory(
                      getParent().getParent(),
                      launcher,
                      envVars,
                      getMavenOpts(listener, envVars),
                      null)
                  : new MavenProcessFactory(
                      getParent().getParent(),
                      launcher,
                      envVars,
                      getMavenOpts(listener, envVars),
                      null));

      ArgumentListBuilder margs = new ArgumentListBuilder("-N", "-B");
      FilePath localRepo = mms.getLocalRepository().locate(MavenBuild.this);
      if (localRepo != null)
        // the workspace must be on this node, so getRemote() is safe.
        margs.add("-Dmaven.repo.local=" + localRepo.getRemote());

      if (mms.getAlternateSettings() != null) {
        if (IOUtils.isAbsolute(mms.getAlternateSettings())) {
          margs.add("-s").add(mms.getAlternateSettings());
        } else {
          FilePath mrSettings = getModuleRoot().child(mms.getAlternateSettings());
          FilePath wsSettings = getWorkspace().child(mms.getAlternateSettings());
          if (!wsSettings.exists() && mrSettings.exists()) wsSettings = mrSettings;

          margs.add("-s").add(wsSettings.getRemote());
        }
      }

      margs.add("-f", getModuleRoot().child("pom.xml").getRemote());
      margs.addTokenized(getProject().getGoals());

      Map<String, String> systemProps = new HashMap<String, String>(envVars);
      // backward compatibility
      systemProps.put("hudson.build.number", String.valueOf(getNumber()));

      if (maven3orLater) {
        // FIXME here for maven 3 builds
        listener
            .getLogger()
            .println("Building single Maven modules is not implemented for Maven 3, yet!");
        return Result.ABORTED;
      } else {
        boolean normalExit = false;
        try {
          Result r =
              process.call(
                  new Builder(
                      listener, new ProxyImpl(), getProject(), margs.toList(), systemProps));
          normalExit = true;
          return r;
        } finally {
          if (normalExit) process.recycle();
          else process.discard();

          // tear down in reverse order
          boolean failed = false;
          for (int i = buildEnvironments.size() - 1; i >= 0; i--) {
            if (!buildEnvironments.get(i).tearDown(MavenBuild.this, listener)) {
              failed = true;
            }
          }
          // WARNING The return in the finally clause will trump any return before
          if (failed) return Result.FAILURE;
        }
      }
    }
Example #11
0
  /** Gets the encrypted usage stat data to be sent to the Hudson server. */
  public String getStatData() throws IOException {
    Jenkins j = Jenkins.getInstance();

    JSONObject o = new JSONObject();
    o.put("stat", 1);
    o.put("install", j.getLegacyInstanceId());
    o.put("servletContainer", j.servletContext.getServerInfo());
    o.put("version", Jenkins.VERSION);

    List<JSONObject> nodes = new ArrayList<JSONObject>();
    for (Computer c : j.getComputers()) {
      JSONObject n = new JSONObject();
      if (c.getNode() == j) {
        n.put("master", true);
        n.put("jvm-vendor", System.getProperty("java.vm.vendor"));
        n.put("jvm-name", System.getProperty("java.vm.name"));
        n.put("jvm-version", System.getProperty("java.version"));
      }
      n.put("executors", c.getNumExecutors());
      DescriptorImpl descriptor = j.getDescriptorByType(DescriptorImpl.class);
      n.put("os", descriptor.get(c));
      nodes.add(n);
    }
    o.put("nodes", nodes);

    List<JSONObject> plugins = new ArrayList<JSONObject>();
    for (PluginWrapper pw : j.getPluginManager().getPlugins()) {
      if (!pw.isActive()) continue; // treat disabled plugins as if they are uninstalled
      JSONObject p = new JSONObject();
      p.put("name", pw.getShortName());
      p.put("version", pw.getVersion());
      plugins.add(p);
    }
    o.put("plugins", plugins);

    JSONObject jobs = new JSONObject();
    List<TopLevelItem> items = j.getAllItems(TopLevelItem.class);
    for (TopLevelItemDescriptor d : Items.all()) {
      int cnt = 0;
      for (TopLevelItem item : items) {
        if (item.getDescriptor() == d) cnt++;
      }
      jobs.put(d.getJsonSafeClassName(), cnt);
    }
    o.put("jobs", jobs);

    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();

      // json -> UTF-8 encode -> gzip -> encrypt -> base64 -> string
      OutputStreamWriter w =
          new OutputStreamWriter(
              new GZIPOutputStream(new CombinedCipherOutputStream(baos, getKey(), "AES")), "UTF-8");
      try {
        o.write(w);
      } finally {
        IOUtils.closeQuietly(w);
      }

      return new String(Base64.encode(baos.toByteArray()));
    } catch (GeneralSecurityException e) {
      throw new Error(e); // impossible
    }
  }
  private void wmiLaunch(final EC2Computer computer, final TaskListener listener)
      throws IOException, InterruptedException, JIException {
    try {
      final PrintStream logger = listener.getLogger();
      final String name = host;

      logger.println(Messages.ManagedWindowsServiceLauncher_ConnectingTo(name));

      InetAddress host = InetAddress.getByName(name);

      try {
        Socket s = new Socket();
        s.connect(new InetSocketAddress(host, 135), 5000);
        s.close();
      } catch (IOException e) {
        logger.println(
            "Failed to connect to port 135 of "
                + name
                + ". Is Windows firewall blocking this port? Or did you disable DCOM service?");
        // again, let it continue.
      }

      JIDefaultAuthInfoImpl auth = createAuth();
      JISession session = JISession.createSession(auth);
      session.setGlobalSocketTimeout(60000);
      SWbemServices services = WMI.connect(session, name);

      String path = computer.getNode().getRemoteFS();
      if (path.indexOf(':') == -1)
        throw new IOException(
            "Remote file system root path of the slave needs to be absolute: " + path);
      SmbFile remoteRoot =
          new SmbFile(
              "smb://" + name + "/" + path.replace('\\', '/').replace(':', '$') + "/",
              createSmbAuth());

      if (!remoteRoot.exists()) remoteRoot.mkdirs();

      try { // does Java exist?
        logger.println("Checking if Java exists");
        WindowsRemoteProcessLauncher wrpl = new WindowsRemoteProcessLauncher(name, auth);
        Process proc = wrpl.launch("%JAVA_HOME%\\bin\\java -fullversion", "c:\\");
        proc.getOutputStream().close();
        IOUtils.copy(proc.getInputStream(), logger);
        proc.getInputStream().close();
        int exitCode = proc.waitFor();
        if (exitCode == 1) { // we'll get this error code if Java is not found
          logger.println("No Java found. Downloading JDK");
          JDKInstaller jdki = new JDKInstaller("jdk-6u16-oth-JPR@CDS-CDS_Developer", true);
          URL jdk = jdki.locate(listener, Platform.WINDOWS, CPU.i386);

          listener.getLogger().println("Installing JDK");
          copyStreamAndClose(
              jdk.openStream(), new SmbFile(remoteRoot, "jdk.exe").getOutputStream());

          String javaDir = path + "\\jdk"; // this is where we install Java to

          WindowsRemoteFileSystem fs = new WindowsRemoteFileSystem(name, createSmbAuth());
          fs.mkdirs(javaDir);

          jdki.install(
              new WindowsRemoteLauncher(listener, wrpl),
              Platform.WINDOWS,
              fs,
              listener,
              javaDir,
              path + "\\jdk.exe");
        }
      } catch (Exception e) {
        e.printStackTrace(listener.error("Failed to prepare Java"));
      }

      String id = generateServiceId(path);
      Win32Service slaveService = services.getService(id);
      if (slaveService == null) {
        logger.println(Messages.ManagedWindowsServiceLauncher_InstallingSlaveService());
        if (!DotNet.isInstalled(2, 0, name, auth)) {
          // abort the launch
          logger.println(Messages.ManagedWindowsServiceLauncher_DotNetRequired());
          return;
        }

        // copy exe
        logger.println(Messages.ManagedWindowsServiceLauncher_CopyingSlaveExe());
        copyStreamAndClose(
            getClass().getResource("/windows-service/jenkins.exe").openStream(),
            new SmbFile(remoteRoot, "jenkins-slave.exe").getOutputStream());

        copySlaveJar(logger, remoteRoot);

        // copy jenkins-slave.xml
        logger.println(Messages.ManagedWindowsServiceLauncher_CopyingSlaveXml());
        String nodeNameEncoded = java.net.URLEncoder.encode(nodeName, "UTF-8").replace("+", "%20");
        String xml =
            generateSlaveXml(
                id,
                "\"%JAVA_HOME%\\bin\\java\"",
                " -jnlpUrl "
                    + Hudson.getInstance().getRootUrl()
                    + "computer/"
                    + nodeNameEncoded
                    + "/slave-agent.jnlp");
        copyStreamAndClose(
            new ByteArrayInputStream(xml.getBytes("UTF-8")),
            new SmbFile(remoteRoot, "jenkins-slave.xml").getOutputStream());

        // install it as a service
        logger.println(Messages.ManagedWindowsServiceLauncher_RegisteringService());
        Document dom = new SAXReader().read(new StringReader(xml));
        Win32Service svc = services.Get("Win32_Service").cast(Win32Service.class);
        int r =
            svc.Create(
                id,
                dom.selectSingleNode("/service/name").getText() + " at " + path,
                path + "\\jenkins-slave.exe",
                Win32OwnProcess,
                0,
                "Manual",
                true);
        if (r != 0) {
          throw new JIException(-1, ("Failed to create a service: " + svc.getErrorMessage(r)));
        }
        slaveService = services.getService(id);
      } else {
        copySlaveJar(logger, remoteRoot);
      }

      logger.println(Messages.ManagedWindowsServiceLauncher_StartingService());
      slaveService.start();

      // wait until we see the port.txt, but don't do so forever
      logger.println(Messages.ManagedWindowsServiceLauncher_WaitingForService());
      SmbFile portFile = new SmbFile(remoteRoot, "port.txt");
      for (int i = 0; !portFile.exists(); i++) {
        if (i >= 30) {
          throw new JIException(-1, Messages.ManagedWindowsServiceLauncher_ServiceDidntRespond());
        }
        Thread.sleep(1000);
      }
      int p = readSmbFile(portFile);

      // connect
      logger.println(Messages.ManagedWindowsServiceLauncher_ConnectingToPort(p));
      final Socket s = new Socket(name, p);

      // ready
      computer.setChannel(
          new BufferedInputStream(new SocketInputStream(s)),
          new BufferedOutputStream(new SocketOutputStream(s)),
          listener.getLogger(),
          new Listener() {
            @Override
            public void onClosed(Channel channel, IOException cause) {
              afterDisconnect(computer, listener);
            }
          });
      // destroy session to free the socket
      JISession.destroySession(session);
    } catch (SmbException e) {
      e.printStackTrace(listener.error(e.getMessage()));
    } catch (DocumentException e) {
      e.printStackTrace(listener.error(e.getMessage()));
    }
  }
Example #13
0
  private void generateStatusPNG(
      String branch,
      String commitSHA1,
      Job project,
      final StaplerRequest req,
      final StaplerResponse rsp)
      throws ServletException, IOException {
    SCMTriggerItem item = SCMTriggerItems.asSCMTriggerItem(project);
    GitSCM gitSCM = getGitSCM(item);

    if (gitSCM == null) {
      throw new IllegalArgumentException("This repo does not use git.");
    }

    Run mainBuild = null;

    if (branch != null) {
      mainBuild = this.getBuildByBranch(project, branch);
    } else if (commitSHA1 != null) {
      mainBuild = this.getBuildBySHA1(project, commitSHA1, false);
    }

    String baseUrl = Jenkins.getInstance().getRootUrl();
    // Remove trailing slash
    if (baseUrl.endsWith("/")) {
      baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
    }
    String imageUrl = "images/unknown.png";
    if (null != mainBuild) {
      Result res = mainBuild.getResult();
      if (mainBuild.isBuilding()) {
        imageUrl = "images/running.png";
      } else if (res == Result.SUCCESS) {
        imageUrl = "images/success.png";
      } else if (res == Result.FAILURE) {
        imageUrl = "images/failed.png";
      } else if (res == Result.UNSTABLE) {
        imageUrl = "images/unstable.png";
      } else {
        imageUrl = "images/unknown.png";
      }
    }
    Authentication old = SecurityContextHolder.getContext().getAuthentication();
    SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
    try {
      URL resourceUrl =
          new URL(
              Jenkins.getInstance().getPlugin("gitlab-plugin").getWrapper().baseResourceURL
                  + imageUrl);
      LOGGER.info("serving image " + resourceUrl.toExternalForm());
      rsp.setHeader("Expires", "Fri, 01 Jan 1984 00:00:00 GMT");
      rsp.setHeader("Cache-Control", "no-cache, private");
      rsp.setHeader("Content-Type", "image/png");
      hudson.util.IOUtils.copy(new File(resourceUrl.toURI()), rsp.getOutputStream());
      rsp.flushBuffer();
    } catch (Exception e) {
      throw HttpResponses.error(500, "Could not generate response.");
    } finally {
      SecurityContextHolder.getContext().setAuthentication(old);
    }
  }
    public PluginWrapper createPluginWrapper(File archive) throws IOException {
        final Manifest manifest;
        URL baseResourceURL;

        File expandDir = null;
        // if .hpi, this is the directory where war is expanded

        boolean isLinked = archive.getName().endsWith(".hpl") || archive.getName().endsWith(".jpl");
        if (isLinked) {
            // resolve the .hpl file to the location of the manifest file
            final String firstLine = IOUtils.readFirstLine(new FileInputStream(archive), "UTF-8");
            if (firstLine.startsWith("Manifest-Version:")) {
                // this is the manifest already
            } else {
                // indirection
                archive = resolve(archive, firstLine);
            }
            // then parse manifest
            FileInputStream in = new FileInputStream(archive);
            try {
                manifest = new Manifest(in);
            } catch (IOException e) {
                throw new IOException2("Failed to load " + archive, e);
            } finally {
                in.close();
            }
        } else {
            if (archive.isDirectory()) {// already expanded
                expandDir = archive;
            } else {
                expandDir = new File(archive.getParentFile(), PluginWrapper.getBaseName(archive));
                explode(archive, expandDir);
            }

            File manifestFile = new File(expandDir, "META-INF/MANIFEST.MF");
            if (!manifestFile.exists()) {
                throw new IOException(
                        "Plugin installation failed. No manifest at "
                                + manifestFile);
            }
            FileInputStream fin = new FileInputStream(manifestFile);
            try {
                manifest = new Manifest(fin);
            } finally {
                fin.close();
            }
        }

        final Attributes atts = manifest.getMainAttributes();

        // TODO: define a mechanism to hide classes
        // String export = manifest.getMainAttributes().getValue("Export");

        List<File> paths = new ArrayList<File>();
        if (isLinked) {
            parseClassPath(manifest, archive, paths, "Libraries", ",");
            parseClassPath(manifest, archive, paths, "Class-Path", " +"); // backward compatibility

            baseResourceURL = resolve(archive,atts.getValue("Resource-Path")).toURI().toURL();
        } else {
            File classes = new File(expandDir, "WEB-INF/classes");
            if (classes.exists())
                paths.add(classes);
            File lib = new File(expandDir, "WEB-INF/lib");
            File[] libs = lib.listFiles(JAR_FILTER);
            if (libs != null)
                paths.addAll(Arrays.asList(libs));

            baseResourceURL = expandDir.toURI().toURL();
        }
        File disableFile = new File(archive.getPath() + ".disabled");
        if (disableFile.exists()) {
            LOGGER.info("Plugin " + archive.getName() + " is disabled");
        }

        // compute dependencies
        List<PluginWrapper.Dependency> dependencies = new ArrayList<PluginWrapper.Dependency>();
        List<PluginWrapper.Dependency> optionalDependencies = new ArrayList<PluginWrapper.Dependency>();
        String v = atts.getValue("Plugin-Dependencies");
        if (v != null) {
            for (String s : v.split(",")) {
                PluginWrapper.Dependency d = new PluginWrapper.Dependency(s);
                if (d.optional) {
                    optionalDependencies.add(d);
                } else {
                    dependencies.add(d);
                }
            }
        }
        for (DetachedPlugin detached : DETACHED_LIST)
            detached.fix(atts,optionalDependencies);

        ClassLoader dependencyLoader = new DependencyClassLoader(getClass().getClassLoader(), archive, Util.join(dependencies,optionalDependencies));
        dependencyLoader = getBaseClassLoader(atts, dependencyLoader);

        return new PluginWrapper(pluginManager, archive, manifest, baseResourceURL,
                createClassLoader(paths, dependencyLoader, atts), disableFile, dependencies, optionalDependencies);
    }