B4J Question Any Library or Class to work with .tar.gz Files (SOLVED)

walterf25

Expert
Licensed User
Longtime User
Hi All, i have searched but have not come across something that works completely, I need to extract the contents of a .tar.gz archive that is around 1.8GB, I have been using the Archiver Library which works but only to ungz the file, which leaves me with only the .tar file, but none of the methods in the Archive library seem to work to untar the file after it has been ungzed.

I have tried both methods in that library.
B4X:
nmfiles = unzip.UnTar(inputdirectory, archivename, outputdirectory)
This does not work, it throws the following error:
tar file exists, untaring
java.lang.ClassFormatError: Invalid index 4 in LocalVariableTable in class file flm/b4a/archiver/TarEntry
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at flm.b4a.archiver.TarInputStream.getNextEntry(TarInputStream.java:150)
at flm.b4a.archiver.ArchiverForB4A.internalUnTar(ArchiverForB4A.java:341)
at flm.b4a.archiver.ArchiverForB4A.UnTar(ArchiverForB4A.java:263)
at com.genesis.hermosabuilddownloads.main._unzip_ungzipdone(main.java:2133)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA$3.run(BA.java:247)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
java.lang.RuntimeException: java.lang.ClassFormatError: Invalid index 4 in LocalVariableTable in class file flm/b4a/archiver/TarEntry
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:120)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA$3.run(BA.java:247)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassFormatError: Invalid index 4 in LocalVariableTable in class file flm/b4a/archiver/TarEntry
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at flm.b4a.archiver.TarInputStream.getNextEntry(TarInputStream.java:150)
at flm.b4a.archiver.ArchiverForB4A.internalUnTar(ArchiverForB4A.java:341)
at flm.b4a.archiver.ArchiverForB4A.UnTar(ArchiverForB4A.java:263)
at com.genesis.hermosabuilddownloads.main._unzip_ungzipdone(main.java:2133)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
... 9 more

And I have also tried this other method:
B4X:
unzip.AsyncUnTarGz(inputdirectory, archivename, outputdirectory, "Untar")
This method does not throw any errors, but it doesn't raise the Sub Untar_UnTarGzDone(CompletedWithoutError As Boolean, NbOfFiles As Int) Event either.

So i'm wondering if anyone has found a solution for this?

Thanks in advanced everyone.

Walter
 

walterf25

Expert
Licensed User
Longtime User
You can download the standalone 7zip tool: https://www.7-zip.org/a/7z1900-extra.7z

All you need is the 7za.exe file. You can then run it with jShell.
Thank you Erel but I was hoping for a better solution, I plan on sharing this with my colleagues at work and I need a solution that will work without having to use or call any external tools such as the 7zip tool, do you know of any libraries that can be wrapped for this purpose? I can try to create a wrapper and release it to the forum.

Thanks,
Walter
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
do you know of any libraries that can be wrapped for this purpose?
No.

I need a solution that will work without having to use or call any external tools such as the 7zip tool
Users will not see that any external tool is called. You will distribute it together with your app.
It is a good solution if you need to unpack large files.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
No.


Users will not see that any external tool is called. You will distribute it together with your app.
It is a good solution if you need to unpack large files.
Oh ok, let me give it a try then, is there a mac version for it?

Walter
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
I was able to get this working with @Erel 's suggestion, I downloaded the standalone 7zip files, copied the .exe and .dll files into the File.DirApp of my project and execute from there, here's the command line I used using the jShell Library, hope anyone else finds this useful.

B4X:
Dim shell As Shell
shell.InitializeDoNotHandleQuotes("shell", "cmd", Array As String("/c", "7za.exe", "x", File.Combine(DOWNLOADFOLDER, Common.buildName), "-so", "|", "7za.exe", "x", "-si", "-ttar", "-o"&filename))
shell.WorkingDirectory = File.DirApp
shell.RunWithOutputEvents(-1)

The DOWNLOADFOLDER is whatever path the .tar.gz archive is downloaded to, in my case every archive is downloaded into the Downloads folder, the Common.buildName variable is the name of the archive for example "xyz.tar.gz" and lastly the filename variable is the directory where the uncompressed and extracted files will be saved to.

7za command line explanation.
the "x" is used to let the 7za tool that we want to extract, an alternative is to use "e" instead of "x"
the "-so" write to stdOut switch
the "|" (pipe) is used to chain two command together
then we see "7za.exe" again as we are chaining two commands the first part is to extract the tar file and the second command is to uncompress the files inside the .tar archive.
the "-si" read from stdIn switch
the "-ttar" Treat the stdin byte stream as a TAR file
the "-o" followed by the path where the files will be extracted to is self explanatory.

Thanks,
Walter
 
Upvote 0
Top