2

I have a function (see below) that copies all files of a specific folder from its own JAR.
For this function (see below too), I want to write tests, but the tests will be executed before the JAR is builded (it's a maven project) .

One important part of this function is that it only knows the folder name, but not the files in this folder so it must "query" for them.

The problem is, that the APIs to "query" for all files of one folder differ whether they work on a JAR (production) or on the file system (test).

My question is:

  • How to test the function that relay on the not yet existing JAR,
  • or how to "combine" the functions (how to decide whether it must the JAR or non JAR way),
  • or (that would be the best) is there any (small lib) that handle this subject?

The first method used for the jar. (production)
This is a little bit modified version of an answer to Copy directory from a jar file:

public class RessourcesUtil {
  ...

  public static void copyResourcesFromJar((String nameOfResourceDirectory, 
                  File destinationDirectory) throws IOException {

      String jarPath = RessourcesUtil.class.getProtectionDomain().getCodeSource().
                     getLocation().getFile();

      Enumeration<JarEntry> jarEntries = new JarFile(jarPath).entries();
      while (jarEntries.hasMoreElements()) {
          JarEntry fileFromJar = (JarEntry) jarEntries.nextElement();

          if (fileFromJar.getName().startsWith(nameOfJarDirectory)) {
              String plainFileName = fileFromJar.getName().
                 replaceAll(nameOfJarDirectory, "");
            
              File fileToCreate = 
                 new File(destinationDirectory + File.separator + plainFileName);

              if (fileFromJar.isDirectory()) {
                  fileToCreate.mkdir();
                  continue;
              }

              createFile(jarFile.getInputStream(fileFromJar), fileToCreate);
          }
      }
  }

  private static void createFile(InputStream inputStream, 
                   File fileToWrite) throws IOException {

        try (FileOutputStream fos = new FileOutputStream(fileToWrite)) {
          IOUtils.copy(inputStream, fos);
      }
   }
}

Second if the resources are not packed in a jar (for testing):

public class RessourcesUtil {
  public static void copyResourcesFromFileSystem(String nameOfResourceDirectory, 
                  File destinationDirectory) throws IOException {

      String classDir = RessourcesUtil.class.getProtectionDomain().getCodeSource().
                     getLocation().getPath();

      File srcDir = new File(classDir + File.separator + nameOfResourceDirectory);
      FileUtils.copyDirectory(new File(srcDir.getPath()), destinationDirectory);
  }
  ...
}

Both are working, but only under the circumstance of packed or unpacked.

Background:

For a project I wrote a multimodul Maven-plugin in Eclipse that can also be used as a standalone.

My resources are in a different modul than my main or my mojo.
Now I need to copy the a specific folder in resources, from my project into a different folder in every run.

P.S.
Copying every single file from resources via getResourcesAsStream is not an option.

Community
  • 1
  • 1
Chris
  • 98
  • 5
  • 1
    If you use Java 7+, why don't you use the zip filesystem provider? – fge May 29 '15 at 08:40
  • @fge I don't think that would work. if the program is already running it won't be able to access itself using the file system – nafas May 29 '15 at 08:41
  • @nafas there is no reason why it can't work; quite the contrary, in fact. You just have to obtain a `FileSystem` and your stuff is done – fge May 29 '15 at 08:43
  • There's one thing I don't quite get; is the jar you speak of on your classpath at runtime or not? – fge May 29 '15 at 08:46
  • Sounds you are misunderstanding the idea of a unit test. For your intention you need to have an integration test which is after the package phase. For this purpose the maven-failsafe-plugin is intended. Or you can use the exec-maven-plugin which can be bound to the integration-test phase. – khmarbaise May 29 '15 at 08:46
  • @fge I'm not 100% sure but I believe u'll get "file is used by another program error" – nafas May 29 '15 at 08:48
  • @fge thanks for the suggestion with the zip filesystem provider, but I would still differ between if I use an unpacked version or a packed version. – Chris May 29 '15 at 09:00
  • @fge the jar is in my classpath. – Chris May 29 '15 at 09:01

1 Answers1

1

Try this approach,

Have your maven build as two parts first part being exclude the folder which you want to copy the files, so once this part is completed you will have your jars ready

second part execute your copying code which takes the input from the jar and moves it to the specified different folder.

Clement Amarnath
  • 5,301
  • 1
  • 21
  • 34
  • This works fine. Now my Test will be executed as Integration-Test, so the JAR is packed and I can test my copyResourcesFromJar method. – Chris May 29 '15 at 09:09