@VisibleForTesting
  Path getJarArtifact() throws IOException {
    Optional<String> classifier = Optional.empty();
    Path buildDirectory = Paths.get(project.getBuild().getDirectory());
    Path outputDirectory = buildDirectory;

    // Read <classifier> and <outputDirectory> from maven-jar-plugin.
    Plugin jarPlugin = project.getPlugin("org.apache.maven.plugins:maven-jar-plugin");
    if (jarPlugin != null) {
      for (PluginExecution execution : jarPlugin.getExecutions()) {
        if ("default-jar".equals(execution.getId())) {
          Xpp3Dom configuration = (Xpp3Dom) execution.getConfiguration();
          classifier = getChildValue(configuration, "classifier");
          Optional<String> directoryString = getChildValue(configuration, "outputDirectory");

          if (directoryString.isPresent()) {
            outputDirectory = project.getBasedir().toPath().resolve(directoryString.get());
          }
          break;
        }
      }
    }

    String finalName = project.getBuild().getFinalName();
    String suffix = ".jar";

    Optional<Xpp3Dom> bootConfiguration = getSpringBootRepackageConfiguration();
    if (bootConfiguration.isPresent()) {
      log(LogEvent.lifecycle("Spring Boot repackaging (fat JAR) detected; using the original JAR"));

      // Spring renames original JAR only when replacing it, so check if the paths are clashing.
      Optional<String> bootFinalName = getChildValue(bootConfiguration.get(), "finalName");
      Optional<String> bootClassifier = getChildValue(bootConfiguration.get(), "classifier");

      boolean sameDirectory = outputDirectory.equals(buildDirectory);
      // If Boot <finalName> is undefined, it uses the default project <finalName>.
      boolean sameFinalName = !bootFinalName.isPresent() || finalName.equals(bootFinalName.get());
      boolean sameClassifier = classifier.equals(bootClassifier);
      if (sameDirectory && sameFinalName && sameClassifier) {
        suffix = ".jar.original";
      }
    }

    String noSuffixJarName = finalName + (classifier.isPresent() ? '-' + classifier.get() : "");
    Path jarPath = outputDirectory.resolve(noSuffixJarName + suffix);
    log(LogEvent.debug("Using JAR: " + jarPath));

    if (".jar".equals(suffix)) {
      return jarPath;
    }

    // "*" in "java -cp *" doesn't work if JAR doesn't end with ".jar". Copy the JAR with a new name
    // ending with ".jar".
    Path tempDirectory = tempDirectoryProvider.newDirectory();
    Path newJarPath = tempDirectory.resolve(noSuffixJarName + ".original.jar");
    Files.copy(jarPath, newJarPath);
    return newJarPath;
  }
@Test
  public void testGetJarArtifact_relativeOutputDirectoryFromJarPlugin() throws IOException {
    when(mockMavenProject.getBasedir()).thenReturn(new File("/base/dir"));
    when(mockBuild.getDirectory()).thenReturn(temporaryFolder.getRoot().toString());
    when(mockBuild.getFinalName()).thenReturn("helloworld-1");

    when(mockMavenProject.getPlugin("org.apache.maven.plugins:maven-jar-plugin"))
        .thenReturn(mockPlugin);
    when(mockPlugin.getExecutions()).thenReturn(Arrays.asList(mockPluginExecution));
    when(mockPluginExecution.getId()).thenReturn("default-jar");
    when(mockPluginExecution.getConfiguration()).thenReturn(pluginConfiguration);
    addXpp3DomChild(pluginConfiguration, "outputDirectory", Paths.get("relative").toString());

    assertThat(mavenProjectProperties.getJarArtifact())
        .isEqualTo(Paths.get("/base/dir/relative/helloworld-1.jar"));
  }