You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by "tuxji (via GitHub)" <gi...@apache.org> on 2023/02/13 16:28:48 UTC

[GitHub] [daffodil] tuxji commented on a diff in pull request #959: Manually extract runtime2 files out of the jar

tuxji commented on code in PR #959:
URL: https://github.com/apache/daffodil/pull/959#discussion_r1104722657


##########
daffodil-runtime2/src/main/scala/org/apache/daffodil/runtime2/CodeGenerator.scala:
##########
@@ -66,21 +62,23 @@ class CodeGenerator(root: Root) extends DFDL.CodeGenerator {
     os.remove.all(codeDir)
 
     // Copy all the C source files from our resources to our code subdirectory
-    // (using synchronized to avoid calling FileSystems.newFileSystem concurrently)
     val resourceUri = Misc.getRequiredResource(resources)
-    mutex.synchronized {
-      val fileSystem = if (resourceUri.getScheme == "jar") {
-        val env: java.util.Map[String, String] = Collections.emptyMap()
-        FileSystems.newFileSystem(resourceUri, env)
-      } else {
-        null
-      }
-      try {
-        val resourceDir = os.Path(if (fileSystem != null) fileSystem.getPath(resources) else Paths.get(resourceUri))
-        os.copy(resourceDir, codeDir)
-      }
-      finally
-        if (fileSystem != null) fileSystem.close()
+    if (resourceUri.getScheme == "jar") {
+      val jarConnection = resourceUri.toURL.openConnection().asInstanceOf[JarURLConnection]
+      val jarFile = jarConnection.getJarFile()
+      jarFile.entries.asScala
+        .filter { entry => ("/" + entry.getName).startsWith(resources) }
+        .filterNot { entry => entry.isDirectory }
+        .foreach { entry =>
+          val entryPath = "/" + entry.getName
+          val subPath = os.SubPath(entryPath.stripPrefix(resources + "/"))
+          val dstPath = codeDir / subPath
+          val stream = jarFile.getInputStream(entry)
+          os.write(dstPath, stream, createFolders = true)

Review Comment:
   The advantage of keeping using `os.copy` is that it will copy the original file's attributes (date/time and permissions).  I'd like to suggest an alternative fix which might work as well:
   
   ```scala
       // Copy all our C resources to the code subdirectory (using synchronized
       // to avoid calling FileSystems.newFileSystem concurrently)
       val resources = "/org/apache/daffodil/runtime2/c"
       val resourceUri = Misc.getRequiredResource(resources)
       if (resourceUri.getScheme == "jar") {
         val env: java.util.Map[String, String] = Collections.emptyMap()
         val fileSystem = Misc.synchronized { FileSystems.newFileSystem(resourceUri, env) }
         try {
           val resourceDir = os.Path(fileSystem.getPath(resources))
           os.copy(resourceDir, codeDir)
         }
         finally fileSystem.close()
       } else {
         val resourceDir = os.Path(Paths.get(resourceUri))
         os.copy(resourceDir, codeDir)
       }
   ```
   
   What do you think?  I've been using that code in another code generator even before this PR was made for a while and it seems to work.  I've also made that improvement to the C code generator in another PR I've been working on to remove Runtime2DataProcessor and merge its code into Runtime2TDMLDFDLProcessor, BTW.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@daffodil.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org