예제 #1
0
  private void maven(String[] goals) {
    if (goals == null) {
      return;
    }

    MavenEmbedder maven = new MavenEmbedder();
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    maven.setClassLoader(classLoader);
    maven.setLogger(new MavenEmbedderConsoleLogger());
    for (String goal : goals) {
      try {
        maven.start();
        File targetDirectory = new File(System.getProperty("user.dir"), "work");
        File pomFile = new File(targetDirectory, "pom.xml");
        MavenProject pom;
        pom = maven.readProjectWithDependencies(pomFile);
        EventMonitor eventMonitor =
            new DefaultEventMonitor(new PlexusLoggerAdapter(new MavenEmbedderConsoleLogger()));
        maven.execute(
            pom,
            Collections.singletonList(goal),
            eventMonitor,
            new ConsoleDownloadMonitor(),
            null,
            targetDirectory);
      } catch (MavenEmbedderException e) {
        e.printStackTrace();
      } catch (ArtifactResolutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (ArtifactNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (ProjectBuildingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (CycleDetectedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (LifecycleExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (BuildFailureException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (DuplicateProjectException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
  protected Artifact resolve(
      String groupId, String artifactId, String version, String type, String classifier)
      throws MojoExecutionException {
    // return project.getArtifactMap().get( groupId + ":" + artifactId );

    Artifact artifact =
        artifactFactory.createArtifactWithClassifier(
            groupId, artifactId, version, type, classifier);
    try {
      resolver.resolve(artifact, remoteRepositories, localRepository);
    } catch (ArtifactNotFoundException e) {
      throw new MojoExecutionException("artifact not found - " + e.getMessage(), e);
    } catch (ArtifactResolutionException e) {
      throw new MojoExecutionException("artifact resolver problem - " + e.getMessage(), e);
    }
    return artifact;
  }
예제 #3
0
  /** @param xstreamObject not null */
  private void addAlias(XStream xstreamObject) {
    try {
      addAlias(xstreamObject, getMavenModelJarFile(), "org.apache.maven.model");
      addAlias(xstreamObject, getMavenSettingsJarFile(), "org.apache.maven.settings");
    } catch (MojoExecutionException e) {
      if (getLog().isDebugEnabled()) {
        getLog().debug("MojoExecutionException: " + e.getMessage(), e);
      }
    } catch (ArtifactResolutionException e) {
      if (getLog().isDebugEnabled()) {
        getLog().debug("ArtifactResolutionException: " + e.getMessage(), e);
      }
    } catch (ArtifactNotFoundException e) {
      if (getLog().isDebugEnabled()) {
        getLog().debug("ArtifactNotFoundException: " + e.getMessage(), e);
      }
    } catch (ProjectBuildingException e) {
      if (getLog().isDebugEnabled()) {
        getLog().debug("ProjectBuildingException: " + e.getMessage(), e);
      }
    }

    // TODO need to handle specific Maven objects like DefaultArtifact?
  }
  private SurefireBooter constructSurefireBooter()
      throws MojoExecutionException, MojoFailureException {
    SurefireBooter surefireBooter = new SurefireBooter();

    Artifact surefireArtifact =
        (Artifact) pluginArtifactMap.get("org.apache.maven.surefire:surefire-booter");
    if (surefireArtifact == null) {
      throw new MojoExecutionException(
          "Unable to locate surefire-booter in the list of plugin artifacts");
    }

    surefireArtifact
        .isSnapshot(); // TODO: this is ridiculous, but it fixes getBaseVersion to be -SNAPSHOT if
    // needed

    Artifact junitArtifact;
    Artifact testNgArtifact;
    try {
      addArtifact(surefireBooter, surefireArtifact);

      junitArtifact = (Artifact) projectArtifactMap.get(junitArtifactName);
      // SUREFIRE-378, junit can have an alternate artifact name
      if (junitArtifact == null && "junit:junit".equals(junitArtifactName)) {
        junitArtifact = (Artifact) projectArtifactMap.get("junit:junit-dep");
      }

      // TODO: this is pretty manual, but I'd rather not require the plugin > dependencies section
      // right now
      testNgArtifact = (Artifact) projectArtifactMap.get(testNGArtifactName);

      if (testNgArtifact != null) {
        VersionRange range = VersionRange.createFromVersionSpec("[4.7,)");
        if (!range.containsVersion(new DefaultArtifactVersion(testNgArtifact.getVersion()))) {
          throw new MojoFailureException(
              "TestNG support requires version 4.7 or above. You have declared version "
                  + testNgArtifact.getVersion());
        }

        convertTestNGParameters();

        if (this.testClassesDirectory != null) {
          properties.setProperty("testng.test.classpath", testClassesDirectory.getAbsolutePath());
        }

        addArtifact(surefireBooter, testNgArtifact);

        // The plugin uses a JDK based profile to select the right testng. We might be explicity
        // using a
        // different one since its based on the source level, not the JVM. Prune using the filter.
        addProvider(
            surefireBooter, "surefire-testng", surefireArtifact.getBaseVersion(), testNgArtifact);
      } else if (junitArtifact != null && junitArtifact.getBaseVersion().startsWith("4")) {
        addProvider(surefireBooter, "surefire-junit4", surefireArtifact.getBaseVersion(), null);
      } else {
        // add the JUnit provider as default - it doesn't require JUnit to be present,
        // since it supports POJO tests.
        addProvider(surefireBooter, "surefire-junit", surefireArtifact.getBaseVersion(), null);
      }
    } catch (ArtifactNotFoundException e) {
      throw new MojoExecutionException(
          "Unable to locate required surefire provider dependency: " + e.getMessage(), e);
    } catch (InvalidVersionSpecificationException e) {
      throw new MojoExecutionException(
          "Error determining the TestNG version requested: " + e.getMessage(), e);
    } catch (ArtifactResolutionException e) {
      throw new MojoExecutionException(
          "Error to resolving surefire provider dependency: " + e.getMessage(), e);
    }

    if (suiteXmlFiles != null && suiteXmlFiles.length > 0 && test == null) {
      if (testNgArtifact == null) {
        throw new MojoExecutionException(
            "suiteXmlFiles is configured, but there is no TestNG dependency");
      }

      // TODO: properties should be passed in here too
      surefireBooter.addTestSuite(
          "org.apache.maven.surefire.testng.TestNGXmlTestSuite",
          new Object[] {
            suiteXmlFiles,
            testSourceDirectory.getAbsolutePath(),
            testNgArtifact.getVersion(),
            testNgArtifact.getClassifier(),
            properties,
            reportsDirectory
          });
    } else {
      List includeList;
      List excludeList;

      if (test != null) {
        // Check to see if we are running a single test. The raw parameter will
        // come through if it has not been set.

        // FooTest -> **/FooTest.java

        includeList = new ArrayList();

        excludeList = new ArrayList();

        if (failIfNoTests == null) {
          failIfNoTests = Boolean.TRUE;
        }

        String[] testRegexes = StringUtils.split(test, ",");

        for (int i = 0; i < testRegexes.length; i++) {
          String testRegex = testRegexes[i];
          if (testRegex.endsWith(".java")) {
            testRegex = testRegex.substring(0, testRegex.length() - 5);
          }
          // Allow paths delimited by '.' or '/'
          testRegex = testRegex.replace('.', '/');
          includeList.add("**/" + testRegex + ".java");
        }
      } else {
        includeList = this.includes;

        excludeList = this.excludes;

        // defaults here, qdox doesn't like the end javadoc value
        // Have to wrap in an ArrayList as surefire expects an ArrayList instead of a List for some
        // reason
        if (includeList == null || includeList.size() == 0) {
          includeList =
              new ArrayList(
                  Arrays.asList(
                      new String[] {"**/Test*.java", "**/*Test.java", "**/*TestCase.java"}));
        }
        if (excludeList == null || excludeList.size() == 0) {
          excludeList = new ArrayList(Arrays.asList(new String[] {"**/*$*"}));
        }
      }

      if (testNgArtifact != null) {
        surefireBooter.addTestSuite(
            "org.apache.maven.surefire.testng.TestNGDirectoryTestSuite",
            new Object[] {
              testClassesDirectory,
              includeList,
              excludeList,
              testSourceDirectory.getAbsolutePath(),
              testNgArtifact.getVersion(),
              testNgArtifact.getClassifier(),
              properties,
              reportsDirectory
            });
      } else {
        String junitDirectoryTestSuite;
        if (junitArtifact != null
            && junitArtifact.getBaseVersion() != null
            && junitArtifact.getBaseVersion().startsWith("4")) {
          junitDirectoryTestSuite = "org.apache.maven.surefire.junit4.JUnit4DirectoryTestSuite";
        } else {
          junitDirectoryTestSuite = "org.apache.maven.surefire.junit.JUnitDirectoryTestSuite";
        }

        // fall back to JUnit, which also contains POJO support. Also it can run
        // classes compiled against JUnit since it has a dependency on JUnit itself.
        surefireBooter.addTestSuite(
            junitDirectoryTestSuite, new Object[] {testClassesDirectory, includeList, excludeList});
      }
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    getLog().debug("Test Classpath :");

    // Check if we need to add configured classes/test classes directories here.
    // If they are configured, we should remove the default to avoid conflicts.
    if (!project.getBuild().getOutputDirectory().equals(classesDirectory.getAbsolutePath())) {
      classpathElements.remove(project.getBuild().getOutputDirectory());
      classpathElements.add(classesDirectory.getAbsolutePath());
    }
    if (!project
        .getBuild()
        .getTestOutputDirectory()
        .equals(testClassesDirectory.getAbsolutePath())) {
      classpathElements.remove(project.getBuild().getTestOutputDirectory());
      classpathElements.add(testClassesDirectory.getAbsolutePath());
    }

    for (Iterator i = classpathElements.iterator(); i.hasNext(); ) {
      String classpathElement = (String) i.next();

      getLog().debug("  " + classpathElement);

      surefireBooter.addClassPathUrl(classpathElement);
    }

    Toolchain tc = getToolchain();

    if (tc != null) {
      getLog().info("Toolchain in surefire-plugin: " + tc);
      if (ForkConfiguration.FORK_NEVER.equals(forkMode)) {
        forkMode = ForkConfiguration.FORK_ONCE;
      }
      if (jvm != null) {
        getLog().warn("Toolchains are ignored, 'executable' parameter is set to " + jvm);
      } else {
        jvm = tc.findTool("java"); // NOI18N
      }
    }

    if (additionalClasspathElements != null) {
      for (Iterator i = additionalClasspathElements.iterator(); i.hasNext(); ) {
        String classpathElement = (String) i.next();

        getLog().debug("  " + classpathElement);

        surefireBooter.addClassPathUrl(classpathElement);
      }
    }

    // ----------------------------------------------------------------------
    // Forking
    // ----------------------------------------------------------------------

    ForkConfiguration fork = new ForkConfiguration();

    // DUNS
    if (project.getPackaging().equals("nar") || (getNarArtifacts().size() > 0)) {
      forkMode = "pertest";
    }

    fork.setForkMode(forkMode);

    processSystemProperties(!fork.isForking());

    if (getLog().isDebugEnabled()) {
      showMap(systemProperties, "system property");
    }

    if (fork.isForking()) {
      useSystemClassLoader = useSystemClassLoader == null ? Boolean.TRUE : useSystemClassLoader;
      fork.setUseSystemClassLoader(useSystemClassLoader.booleanValue());
      fork.setUseManifestOnlyJar(useManifestOnlyJar);

      fork.setSystemProperties(systemProperties);

      if ("true".equals(debugForkedProcess)) {
        debugForkedProcess =
            "-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005";
      }

      fork.setDebugLine(debugForkedProcess);

      if (jvm == null || "".equals(jvm)) {
        // use the same JVM as the one used to run Maven (the "java.home" one)
        jvm = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
        getLog().debug("Using JVM: " + jvm);
      }

      fork.setJvmExecutable(jvm);

      if (workingDirectory != null) {
        fork.setWorkingDirectory(workingDirectory);
      } else {
        fork.setWorkingDirectory(basedir);
      }

      // BEGINDUNS
      if (argLine == null) {
        argLine = "";
      }

      StringBuffer javaLibraryPath = new StringBuffer();
      if (testJNIModule()) {
        // Add libraries to java.library.path for testing
        File jniLibraryPathEntry =
            getLayout()
                .getLibDirectory(
                    getTargetDirectory(),
                    getMavenProject().getArtifactId(),
                    getMavenProject().getVersion(),
                    getAOL().toString(),
                    Library.JNI);
        if (jniLibraryPathEntry.exists()) {
          getLog().debug("Adding library directory to java.library.path: " + jniLibraryPathEntry);
          if (javaLibraryPath.length() > 0) {
            javaLibraryPath.append(File.pathSeparator);
          }
          javaLibraryPath.append(jniLibraryPathEntry);
        }

        File sharedLibraryPathEntry =
            getLayout()
                .getLibDirectory(
                    getTargetDirectory(),
                    getMavenProject().getArtifactId(),
                    getMavenProject().getVersion(),
                    getAOL().toString(),
                    Library.SHARED);
        if (sharedLibraryPathEntry.exists()) {
          getLog()
              .debug("Adding library directory to java.library.path: " + sharedLibraryPathEntry);
          if (javaLibraryPath.length() > 0) {
            javaLibraryPath.append(File.pathSeparator);
          }
          javaLibraryPath.append(sharedLibraryPathEntry);
        }

        // add jar file to classpath, as one may want to read a
        // properties file for artifactId and version
        String narFile = "target/" + project.getArtifactId() + "-" + project.getVersion() + ".jar";
        getLog().debug("Adding to surefire test classpath: " + narFile);
        surefireBooter.addClassPathUrl(narFile);
      }

      List dependencies =
          getNarArtifacts(); // TODO: get seems heavy, not sure if we can push this up to before the
                             // fork to use it multiple times.
      for (Iterator i = dependencies.iterator(); i.hasNext(); ) {
        NarArtifact dependency = (NarArtifact) i.next();
        // FIXME this should be overridable
        // NarInfo info = dependency.getNarInfo();
        // String binding = info.getBinding(getAOL(), Library.STATIC);
        // NOTE: fixed to shared, jni
        String[] bindings = {Library.SHARED, Library.JNI};
        for (int j = 0; j < bindings.length; j++) {
          String binding = bindings[j];
          if (!binding.equals(Library.STATIC)) {
            File depLibPathEntry =
                getLayout()
                    .getLibDirectory(
                        getUnpackDirectory(),
                        dependency.getArtifactId(),
                        dependency.getVersion(),
                        getAOL().toString(),
                        binding);
            if (depLibPathEntry.exists()) {
              getLog()
                  .debug("Adding dependency directory to java.library.path: " + depLibPathEntry);
              if (javaLibraryPath.length() > 0) {
                javaLibraryPath.append(File.pathSeparator);
              }
              javaLibraryPath.append(depLibPathEntry);
            }
          }
        }
      }

      // add final javalibrary path
      if (javaLibraryPath.length() > 0) {
        // NOTE java.library.path only works for the jni lib itself, and
        // not for its dependent shareables.
        // NOTE: java.library.path does not work with arguments with
        // spaces as
        // SureFireBooter splits the line in parts and then quotes
        // it wrongly
        NarUtil.addLibraryPathToEnv(javaLibraryPath.toString(), environmentVariables, getOS());
      }

      // necessary to find WinSxS
      if (getOS().equals(OS.WINDOWS)) {
        environmentVariables.put(
            "SystemRoot", NarUtil.getEnv("SystemRoot", "SystemRoot", "C:\\Windows"));
      }
      // ENDDUNS

      fork.setArgLine(argLine);

      fork.setEnvironmentVariables(environmentVariables);

      if (getLog().isDebugEnabled()) {
        showMap(environmentVariables, "environment variable");

        fork.setDebug(true);
      }

      if (argLine != null) {
        List args = Arrays.asList(argLine.split(" "));
        if (args.contains("-da") || args.contains("-disableassertions")) {
          enableAssertions = false;
        }
      }
    }

    surefireBooter.setFailIfNoTests(failIfNoTests == null ? false : failIfNoTests.booleanValue());

    surefireBooter.setForkedProcessTimeoutInSeconds(forkedProcessTimeoutInSeconds);

    surefireBooter.setRedirectTestOutputToFile(redirectTestOutputToFile);

    surefireBooter.setForkConfiguration(fork);

    surefireBooter.setChildDelegation(childDelegation);

    surefireBooter.setEnableAssertions(enableAssertions);

    surefireBooter.setReportsDirectory(reportsDirectory);

    addReporters(surefireBooter, fork.isForking());

    return surefireBooter;
  }
  @Override
  public void execute() throws MojoExecutionException, MojoFailureException {
    validateParameters();

    /* outline:
    - compute checksum of "normalized" package.json (ignore whitespace, eols etc)
    - if it equals to current node_modules/package.json.md5, DONE
    - look it up in repo
        - if NOT FOUND, create one
    - unpack it into node_modules
    - invoke "npm rebuild" to adjust symlinks, executable flags etc
    */

    try {
      final String normalizedPackageJson = readPackageJson(packageJson, anonymize);
      final String packageJsonHash = Utils.md5sum(normalizedPackageJson);
      final File oldHashFile = new File(node_modules, "package.json.hash");
      final String oldHash = oldHashFile.exists() ? FileUtils.fileRead(oldHashFile) : "__NONE__";
      if (oldHash.equals(packageJsonHash)) {
        getLog()
            .info(
                String.format(
                    "No change in %s (#%s), keeping %s",
                    packageJson, packageJsonHash, node_modules));
      } else {
        getLog()
            .info(
                String.format(
                    "Differs from previous hash: %s, updating content of %s",
                    oldHash, node_modules));

        // repository lookup
        getLog()
            .info(
                String.format(
                    "Artifact %s:%s:%s", binaryGroupId, binaryArtifactId, packageJsonHash));
        final Artifact artifact =
            factory.createBuildArtifact(
                binaryGroupId, binaryArtifactId, packageJsonHash, archiveType);

        if (node_modules.isDirectory()) {
          final File backup = new File(workdir, "backup/" + node_modules.getName());
          if (backup.isDirectory()) {
            FileUtils.deleteDirectory(backup);
          } else if (backup.exists()) {
            backup.delete();
          }
          getLog().info(String.format("Thrashing %s to %s", node_modules, backup));
          FileUtils.rename(node_modules, backup);
        }
        final long startTime = System.currentTimeMillis();
        try {
          getLog().info(String.format("Trying to resolve artifact %s", artifact));
          resolver.resolveAlways(artifact, remoteRepositories, localRepository);
          getLog()
              .info(
                  String.format(
                      "Resolution (possibly including downloads) took %d millis",
                      System.currentTimeMillis() - startTime));
          unpack(artifact.getFile());
        } catch (ArtifactNotFoundException e) {
          getLog()
              .warn(
                  String.format(
                      "Resolution failed after %d millis", System.currentTimeMillis() - startTime));
          // TODO: only if allowNpmInstall; otherwise inform the user to set this flag and deploy
          // resulting artifact to a repository shared with others, so that insecure network access
          // is
          // minimized and under supervision of a user
          if (allowNpmInstall) {
            pack(artifact, normalizedPackageJson);
          } else {
            getLog().error(npmInstallNotAllowedMsg);
            throw new MojoExecutionException("Invoking npm install is NOT allowed");
          }
        }

        // save checksum
        getLog().info(String.format("Saving hash marker into %s", oldHashFile));
        FileUtils.fileWrite(oldHashFile, packageJsonHash);
        getLog().info(String.format("Directory %s has been successfully recreated", node_modules));
      }
    } catch (IOException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (NoSuchAlgorithmException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (ArtifactResolutionException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (CommandLineException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (InterruptedException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    }
  }
  /**
   * Resolve project dependencies. Manual resolution is needed in order to avoid resoltion of
   * multiproject artifacts (if projects will be linked each other an installed jar is not needed)
   * and to avoid a failure when a jar is missing.
   *
   * @throws MojoExecutionException if dependencies can't be resolved
   * @return resoved IDE dependencies, with attached jars for non-reactor dependencies
   */
  protected IdeDependency[] doDependencyResolution() throws MojoExecutionException {
    MavenProject project = getProject();
    ArtifactRepository localRepo = getLocalRepository();

    List dependencies = getProject().getDependencies();

    // Collect the list of resolved IdeDependencies.
    List dependencyList = new ArrayList();

    if (dependencies != null) {
      Map managedVersions =
          createManagedVersionMap(
              getArtifactFactory(), project.getId(), project.getDependencyManagement());

      ArtifactResolutionResult artifactResolutionResult = null;

      try {

        List listeners = new ArrayList();

        if (logger.isDebugEnabled()) {
          listeners.add(new DebugResolutionListener(logger));
        }

        listeners.add(new WarningResolutionListener(logger));

        artifactResolutionResult =
            artifactCollector.collect(
                getProjectArtifacts(),
                project.getArtifact(),
                managedVersions,
                localRepo,
                project.getRemoteArtifactRepositories(),
                getArtifactMetadataSource(),
                null,
                listeners);
      } catch (ArtifactResolutionException e) {
        getLog().debug(e.getMessage(), e);
        getLog()
            .error(
                Messages.getString(
                    "artifactresolution",
                    new Object[] { // $NON-NLS-1$
                      e.getGroupId(), e.getArtifactId(), e.getVersion(), e.getMessage()
                    }));

        // if we are here artifactResolutionResult is null, create a project without dependencies
        // but don't fail
        // (this could be a reactor projects, we don't want to fail everything)
        return new IdeDependency[0];
      }

      // keep track of added reactor projects in order to avoid duplicates
      Set emittedReactorProjectId = new HashSet();

      for (Iterator i = artifactResolutionResult.getArtifactResolutionNodes().iterator();
          i.hasNext(); ) {
        ResolutionNode node = (ResolutionNode) i.next();
        Artifact art = node.getArtifact();
        boolean isReactorProject = getUseProjectReferences() && isAvailableAsAReactorProject(art);

        // don't resolve jars for reactor projects
        if (!isReactorProject) {
          try {
            artifactResolver.resolve(art, node.getRemoteRepositories(), localRepository);
          } catch (ArtifactNotFoundException e) {
            getLog().debug(e.getMessage(), e);
            getLog()
                .warn(
                    Messages.getString(
                        "artifactdownload",
                        new Object[] { // $NON-NLS-1$
                          e.getGroupId(), e.getArtifactId(), e.getVersion(), e.getMessage()
                        }));
          } catch (ArtifactResolutionException e) {
            getLog().debug(e.getMessage(), e);
            getLog()
                .warn(
                    Messages.getString(
                        "artifactresolution",
                        new Object[] { // $NON-NLS-1$
                          e.getGroupId(), e.getArtifactId(), e.getVersion(), e.getMessage()
                        }));
          }
        }

        if (!isReactorProject
            || emittedReactorProjectId.add(art.getGroupId() + '-' + art.getArtifactId())) {

          IdeDependency dep =
              new IdeDependency(
                  art.getGroupId(),
                  art.getArtifactId(),
                  art.getVersion(),
                  isReactorProject,
                  Artifact.SCOPE_TEST.equals(art.getScope()),
                  Artifact.SCOPE_SYSTEM.equals(art.getScope()),
                  Artifact.SCOPE_PROVIDED.equals(art.getScope()),
                  art.getArtifactHandler().isAddedToClasspath(),
                  art.getFile(),
                  art.getType());

          dependencyList.add(dep);
        }
      }

      // @todo a final report with the list of missingArtifacts?

    }

    IdeDependency[] deps =
        (IdeDependency[]) dependencyList.toArray(new IdeDependency[dependencyList.size()]);

    return deps;
  }
  public void execute() throws MojoExecutionException, MojoFailureException {
    if (this.skip) {
      getLog().info("skip execution");
      return;
    }
    // project.addAttachedArtifact(  );
    File warExecFile = new File(buildDirectory, finalName);
    if (warExecFile.exists()) {
      warExecFile.delete();
    }

    File execWarJar = new File(buildDirectory, finalName);

    FileOutputStream execWarJarOutputStream = null;
    ArchiveOutputStream os = null;
    File tmpPropertiesFile = null;
    File tmpManifestFile = null;
    FileOutputStream tmpPropertiesFileOutputStream = null;
    PrintWriter tmpManifestWriter = null;

    try {

      tmpPropertiesFile = new File(buildDirectory, "war-exec.properties");
      if (tmpPropertiesFile.exists()) {
        tmpPropertiesFile.delete();
      }
      tmpPropertiesFile.getParentFile().mkdirs();

      tmpManifestFile = new File(buildDirectory, "war-exec.manifest");
      if (tmpManifestFile.exists()) {
        tmpManifestFile.delete();
      }
      tmpPropertiesFileOutputStream = new FileOutputStream(tmpPropertiesFile);
      execWarJar.getParentFile().mkdirs();
      execWarJar.createNewFile();
      execWarJarOutputStream = new FileOutputStream(execWarJar);

      tmpManifestWriter = new PrintWriter(tmpManifestFile);

      // store :
      // * wars in the root: foo.war
      // * tomcat jars
      // * file tomcat.standalone.properties with possible values :
      //   * useServerXml=true/false to use directly the one provided
      //   * enableNaming=true/false
      //   * wars=foo.war|contextpath;bar.war  ( |contextpath is optionnal if empty use the war name
      // )
      //   * accessLogValveFormat=
      //   * connectorhttpProtocol: HTTP/1.1 or org.apache.coyote.http11.Http11NioProtocol
      // * optionnal: conf/ with usual tomcat configuration files
      // * MANIFEST with Main-Class

      Properties properties = new Properties();

      properties.put(
          Tomcat7Runner.ARCHIVE_GENERATION_TIMESTAMP_KEY,
          Long.toString(System.currentTimeMillis()));
      properties.put(Tomcat7Runner.ENABLE_NAMING_KEY, Boolean.toString(enableNaming));
      properties.put(Tomcat7Runner.ACCESS_LOG_VALVE_FORMAT_KEY, accessLogValveFormat);
      properties.put(Tomcat7Runner.HTTP_PROTOCOL_KEY, connectorHttpProtocol);

      os =
          new ArchiveStreamFactory()
              .createArchiveOutputStream(ArchiveStreamFactory.JAR, execWarJarOutputStream);

      if ("war".equals(project.getPackaging())) {

        os.putArchiveEntry(new JarArchiveEntry(StringUtils.removeStart(path, "/") + ".war"));
        IOUtils.copy(new FileInputStream(projectArtifact.getFile()), os);
        os.closeArchiveEntry();

        properties.put(Tomcat7Runner.WARS_KEY, StringUtils.removeStart(path, "/") + ".war|" + path);
      } else if (warRunDependencies != null && !warRunDependencies.isEmpty()) {
        for (WarRunDependency warRunDependency : warRunDependencies) {
          if (warRunDependency.dependency != null) {
            Dependency dependency = warRunDependency.dependency;
            Artifact artifact =
                artifactFactory.createArtifactWithClassifier(
                    dependency.getGroupId(),
                    dependency.getArtifactId(),
                    dependency.getVersion(),
                    dependency.getType(),
                    dependency.getClassifier());

            artifactResolver.resolve(artifact, this.remoteRepos, this.local);

            File warFileToBundle = new File(resolvePluginWorkDir(), artifact.getFile().getName());
            FileUtils.copyFile(artifact.getFile(), warFileToBundle);

            if (warRunDependency.contextXml != null) {
              warFileToBundle = addContextXmlToWar(warRunDependency.contextXml, warFileToBundle);
            }
            final String warFileName = artifact.getFile().getName();
            os.putArchiveEntry(new JarArchiveEntry(warFileName));
            IOUtils.copy(new FileInputStream(warFileToBundle), os);
            os.closeArchiveEntry();
            String propertyWarValue = properties.getProperty(Tomcat7Runner.WARS_KEY);
            String contextPath =
                StringUtils.isEmpty(warRunDependency.contextPath)
                    ? "/"
                    : warRunDependency.contextPath;
            if (propertyWarValue != null) {
              properties.put(
                  Tomcat7Runner.WARS_KEY, propertyWarValue + ";" + warFileName + "|" + contextPath);
            } else {
              properties.put(Tomcat7Runner.WARS_KEY, warFileName + "|" + contextPath);
            }
          }
        }
      }

      if (serverXml != null && serverXml.exists()) {
        os.putArchiveEntry(new JarArchiveEntry("conf/server.xml"));
        IOUtils.copy(new FileInputStream(serverXml), os);
        os.closeArchiveEntry();
        properties.put(Tomcat7Runner.USE_SERVER_XML_KEY, Boolean.TRUE.toString());
      } else {
        properties.put(Tomcat7Runner.USE_SERVER_XML_KEY, Boolean.FALSE.toString());
      }

      os.putArchiveEntry(new JarArchiveEntry("conf/web.xml"));
      IOUtils.copy(getClass().getResourceAsStream("/conf/web.xml"), os);
      os.closeArchiveEntry();

      properties.store(tmpPropertiesFileOutputStream, "created by Apache Tomcat Maven plugin");

      tmpPropertiesFileOutputStream.flush();
      tmpPropertiesFileOutputStream.close();

      os.putArchiveEntry(new JarArchiveEntry(Tomcat7RunnerCli.STAND_ALONE_PROPERTIES_FILENAME));
      IOUtils.copy(new FileInputStream(tmpPropertiesFile), os);
      os.closeArchiveEntry();

      // add tomcat classes
      for (Artifact pluginArtifact : pluginArtifacts) {
        if (StringUtils.equals("org.apache.tomcat", pluginArtifact.getGroupId())
            || StringUtils.equals("org.apache.tomcat.embed", pluginArtifact.getGroupId())
            || StringUtils.equals("org.eclipse.jdt.core.compiler", pluginArtifact.getGroupId())
            || StringUtils.equals("commons-cli", pluginArtifact.getArtifactId())
            || StringUtils.equals("tomcat7-war-runner", pluginArtifact.getArtifactId())) {
          JarFile jarFile = new JarFile(pluginArtifact.getFile());
          extractJarToArchive(jarFile, os);
        }
      }

      // add extra dependencies
      if (extraDependencies != null && !extraDependencies.isEmpty()) {
        for (Dependency dependency : extraDependencies) {
          // String groupId, String artifactId, String version, String scope, String type
          Artifact artifact =
              artifactFactory.createArtifact(
                  dependency.getGroupId(),
                  dependency.getArtifactId(),
                  dependency.getVersion(),
                  dependency.getScope(),
                  dependency.getType());

          artifactResolver.resolve(artifact, this.remoteRepos, this.local);
          JarFile jarFile = new JarFile(artifact.getFile());
          extractJarToArchive(jarFile, os);
        }
      }

      Manifest manifest = new Manifest();

      Manifest.Attribute mainClassAtt = new Manifest.Attribute();
      mainClassAtt.setName("Main-Class");
      mainClassAtt.setValue(mainClass);
      manifest.addConfiguredAttribute(mainClassAtt);

      manifest.write(tmpManifestWriter);
      tmpManifestWriter.flush();
      tmpManifestWriter.close();

      os.putArchiveEntry(new JarArchiveEntry("META-INF/MANIFEST.MF"));
      IOUtils.copy(new FileInputStream(tmpManifestFile), os);
      os.closeArchiveEntry();

      if (attachArtifact) {
        // MavenProject project, String artifactType, String artifactClassifier, File artifactFile
        projectHelper.attachArtifact(
            project, attachArtifactClassifierType, attachArtifactClassifier, execWarJar);
      }

      if (extraResources != null) {
        for (ExtraResource extraResource : extraResources) {

          DirectoryScanner directoryScanner = new DirectoryScanner();
          directoryScanner.setBasedir(extraResource.getDirectory());
          directoryScanner.addDefaultExcludes();
          directoryScanner.setExcludes(toStringArray(extraResource.getExcludes()));
          directoryScanner.setIncludes(toStringArray(extraResource.getIncludes()));
          directoryScanner.scan();
          for (String includeFile : directoryScanner.getIncludedFiles()) {
            getLog().debug("include file:" + includeFile);
            os.putArchiveEntry(new JarArchiveEntry(includeFile));
            IOUtils.copy(
                new FileInputStream(new File(extraResource.getDirectory(), includeFile)), os);
            os.closeArchiveEntry();
          }
        }
      }

      if (tomcatConfigurationFilesDirectory != null && tomcatConfigurationFilesDirectory.exists()) {
        // Because its the tomcat default dir for configs
        String aConfigOutputDir = "conf/";
        copyDirectoryContentIntoArchive(tomcatConfigurationFilesDirectory, aConfigOutputDir, os);
      }

    } catch (ManifestException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (IOException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (ArchiveException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (ArtifactNotFoundException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (ArtifactResolutionException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } finally {
      IOUtils.closeQuietly(os);
      IOUtils.closeQuietly(tmpManifestWriter);
      IOUtils.closeQuietly(execWarJarOutputStream);
      IOUtils.closeQuietly(tmpPropertiesFileOutputStream);
    }
  }