Skip to content

#2176: Add 7z archive extraction support#2177

Open
laert-ll wants to merge 14 commits into
devonfw:mainfrom
laert-ll:feature/2176-7z-extraction-support
Open

#2176: Add 7z archive extraction support#2177
laert-ll wants to merge 14 commits into
devonfw:mainfrom
laert-ll:feature/2176-7z-extraction-support

Conversation

@laert-ll

@laert-ll laert-ll commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

This PR fixes #2176

Implemented changes:

  • Added the xz dependency, which Commons Compress needs to decode 7z's LZMA/LZMA2 streams.
  • Extraction preserves Unix file permissions and restores symbolic links.
  • Added extraction progress bar.
  • Added tests and .7z fixtures covering content, permission preservation, and symlink restoration.

Testing instructions

Run the 7z tests: mvn -Dtest=FileAccessImplTest#test7zExtraction+test7zExtractionWithFilePermissions+test7zExtractionWithSymbolicLink -pl cli test and check if all three pass.

Optional: What would also properly test the functionality, is switching to the Ruby branch, rebasing this branch onto it, and testing that the Ruby installation goes through, where we can actually see the 7z extraction process (along with the progress bars and everything).

Checklist for this PR

Make sure everything is checked before merging this PR. For further info please also see
our DoD.

  • When running mvn clean test locally all tests pass and build is successful
  • PR title is of the form #«issue-id»: «brief summary» (e.g. #921: fixed setup.bat). If no issue ID exists, title only.
  • PR top-level comment summarizes what has been done and contains link to addressed issue(s)
  • PR and issue(s) have suitable labels
  • Issue is set to In Progress and assigned to you or there is no issue (might happen for very small PRs)
  • You followed all coding conventions
  • You have added the issue implemented by your PR in CHANGELOG.adoc unless issue is labeled
    with internal
  • You have formulated clear instructions on how to test your contribution under "Testing instructions"

@github-project-automation github-project-automation Bot moved this to 🆕 New in IDEasy board Jul 20, 2026
@laert-ll laert-ll self-assigned this Jul 20, 2026
@laert-ll laert-ll moved this from 🆕 New to 🏗 In progress in IDEasy board Jul 20, 2026
@coveralls

coveralls commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 29939760396

Coverage increased (+0.07%) to 72.561%

Details

  • Coverage increased (+0.07%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 186 coverage regressions across 2 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

186 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
com/devonfw/tools/ide/io/FileAccessImpl.java 185 68.87%
com/devonfw/tools/ide/version/VersionSegment.java 1 91.86%

Coverage Stats

Coverage Status
Relevant Lines: 16997
Covered Lines: 12859
Line Coverage: 75.65%
Relevant Branches: 7603
Covered Branches: 4991
Branch Coverage: 65.65%
Branches in Coverage %: Yes
Coverage Strength: 3.21 hits per line

💛 - Coveralls

@laert-ll
laert-ll force-pushed the feature/2176-7z-extraction-support branch 2 times, most recently from 9b6a208 to 43c5584 Compare July 21, 2026 10:25
@laert-ll laert-ll added enhancement New feature or request install installation process of IDE + tools and install commandlet labels Jul 21, 2026
@laert-ll
laert-ll marked this pull request as ready for review July 21, 2026 13:26
@laert-ll laert-ll changed the title #2176: add 7z archive extraction support #2176: Add 7z archive extraction support Jul 21, 2026
@laert-ll laert-ll moved this from 🏗 In progress to Team Review in IDEasy board Jul 21, 2026
@vivu001 vivu001 self-assigned this Jul 21, 2026
@laert-ll laert-ll mentioned this pull request Jul 22, 2026
16 tasks
@laert-ll
laert-ll force-pushed the feature/2176-7z-extraction-support branch from 7b4ff69 to c89c706 Compare July 22, 2026 04:58
Comment thread cli/src/main/java/com/devonfw/tools/ide/io/FileAccessImpl.java
@vivu001

vivu001 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

I tried building the app with GraalVM, but it hit these errors:

Build resources:
 - 25.59GB of memory (75.6% of system memory, less than 8GB of memory available)
 - 28 thread(s) (100.0% of 28 available processor(s), determined at start)
[2/8] Performing analysis...  []                                                                        (10.6s @ 1.48GB)
    8,055 types,  12,534 fields, and  40,400 methods found reachable
    2,582 types,      64 fields, and   1,633 methods registered for reflection
       13 downcalls and 1 upcalls registered for foreign access
        1 native library: winhttp

6 fatal errors detected:
Fatal error: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: An object of type 'org.tukaani.xz.IA64Options' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.

You now have two options to resolve this:

1) If it is intended that objects of type 'org.tukaani.xz.IA64Options' are persisted in the image heap, add 

    '--initialize-at-build-time=org.tukaani.xz.IA64Options'

to the native-image arguments. Note that initializing new types can store additional objects to the heap. It is advised to check the static fields of 'org.tukaani.xz.IA64Options' to see if they are safe for build-time initialization,  and that they do not contain any sensitive data that should not become part of the image.

2) If these objects should not be stored in the image heap, you can use 

    '--trace-object-instantiation=org.tukaani.xz.IA64Options'

to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with 

    '--initialize-at-run-time=<culprit>'

to prevent the instantiation of the object.

If you are seeing this message after upgrading to a new GraalVM release, this means that some objects ended up in the image heap without their type being marked with --initialize-at-build-time.
To fix this, include '--initialize-at-build-time=org.tukaani.xz.IA64Options' in your configuration. If the classes do not originate from your code, it is advised to update all library or framework dependencies to the latest version before addressing this error.

The following detailed trace displays from which field in the code the object was reached.
Object was reached by
  reading field org.apache.commons.compress.archivers.sevenz.Coders$BCJDecoder.opts of constant 
    org.apache.commons.compress.archivers.sevenz.Coders$BCJDecoder@59adf3c1: org.apache.commons.compress.archivers.sevenz.Coders$BCJDecoder@59adf3c1
  reading field java.util.HashMap$Node.value of constant 
    java.util.HashMap$Node@3c181e12: BCJ_IA64_FILTER=org.apache.commons.compress.archivers.sevenz.Coders$BCJDecoder@5...
  reading field java.util.HashMap$Node.next of constant 
    java.util.HashMap$Node@3f479abc: LZMA=org.apache.commons.compress.archivers.sevenz.LZMADecoder@3599d104
  indexing into array java.util.HashMap$Node[]@4a937916: [Ljava.util.HashMap$Node;@4a937916 at index 7
  reading field java.util.HashMap.table of constant 
    org.apache.commons.compress.archivers.sevenz.Coders$1@6b0544f2: {DEFLATE=org.apache.commons.compress.archivers.sevenz.Coders$DeflateDecoder@627a...
  scanning root org.apache.commons.compress.archivers.sevenz.Coders$1@6b0544f2: {DEFLATE=org.apache.commons.compress.archivers.sevenz.Coders$DeflateDecoder@627a... embedded in
    org.apache.commons.compress.archivers.sevenz.Coders.findByMethod(Coders.java:240)
  parsing method org.apache.commons.compress.archivers.sevenz.Coders.findByMethod(Coders.java:240) reachable via the parsing context
    at org.apache.commons.compress.archivers.sevenz.Coders.addDecoder(Coders.java:224)
    at org.apache.commons.compress.archivers.sevenz.SevenZFile.readEncodedHeader(SevenZFile.java:1212)
    at org.apache.commons.compress.archivers.sevenz.SevenZFile.initializeArchive(SevenZFile.java:1087)
    at org.apache.commons.compress.archivers.sevenz.SevenZFile.readHeaders(SevenZFile.java:1520)
    at org.apache.commons.compress.archivers.sevenz.SevenZFile.<init>(SevenZFile.java:619)
    at org.apache.commons.compress.archivers.sevenz.SevenZFile$Builder.get(SevenZFile.java:193)
    at com.devonfw.tools.ide.io.FileAccessImpl.extract7z(FileAccessImpl.java:1056)
    at com.devonfw.tools.ide.io.FileAccessImpl.extract(FileAccessImpl.java:718)
    at com.devonfw.tools.ide.tool.LocalToolCommandlet.installDownloadedToolPayload(LocalToolCommandlet.java:271)
    at com.devonfw.tools.ide.tool.LocalToolCommandlet.performToolInstallation(LocalToolCommandlet.java:250)
    at com.devonfw.tools.ide.tool.LocalToolCommandlet.installTool(LocalToolCommandlet.java:205)
    at com.devonfw.tools.ide.tool.LocalToolCommandlet.doInstallStep(LocalToolCommandlet.java:96)
    at com.devonfw.tools.ide.tool.LocalToolCommandlet.doInstall(LocalToolCommandlet.java:86)
    at com.devonfw.tools.ide.tool.ToolCommandlet.install(ToolCommandlet.java:351)
    at com.devonfw.tools.ide.tool.ToolCommandlet.runTool(ToolCommandlet.java:276)
    at com.devonfw.tools.ide.tool.ToolCommandlet.runTool(ToolCommandlet.java:257)
    at com.devonfw.tools.ide.tool.python.PythonRepository.fetchUvPythonList(PythonRepository.java:89)
    at com.devonfw.tools.ide.tool.python.PythonRepository.computeSortedVersions(PythonRepository.java:65)
    at com.devonfw.tools.ide.tool.python.PythonRepository.getSortedVersions(PythonRepository.java:58)
    at com.devonfw.tools.ide.property.VersionProperty.completeVersion(VersionProperty.java:84)
    at com.devonfw.tools.ide.property.VersionProperty.completeValue(VersionProperty.java:64)
    at com.devonfw.tools.ide.property.Property.apply(Property.java:403)
    at com.devonfw.tools.ide.property.KeywordProperty.apply(KeywordProperty.java:75)
    at com.devonfw.tools.ide.commandlet.CommandletManagerImpl$CommandletFinder.findNext(CommandletManagerImpl.java:331)
    at com.devonfw.tools.ide.commandlet.CommandletManagerImpl$CommandletFinder.<init>(CommandletManagerImpl.java:293)
    at com.devonfw.tools.ide.commandlet.CommandletManagerImpl.findCommandlet(CommandletManagerImpl.java:269)
    at com.devonfw.tools.ide.context.AbstractIdeContext.run(AbstractIdeContext.java:1205)
    at com.devonfw.tools.ide.cli.Ideasy.runOrThrow(Ideasy.java:92)
    at com.devonfw.tools.ide.cli.Ideasy.run(Ideasy.java:56)
    at com.devonfw.tools.ide.cli.Ideasy.main(Ideasy.java:138)
    at com.oracle.svm.core.JavaMainWrapper.invokeMain(JavaMainWrapper.java:189)
    at com.oracle.svm.core.JavaMainWrapper.runCore0(JavaMainWrapper.java:232)
    at com.oracle.svm.core.JavaMainWrapper.doRun(JavaMainWrapper.java:299)
    at com.oracle.svm.core.code.IsolateEnterStub.JavaMainWrapper_run_XNhh1mz2Ib2aPR1wdv014D(generated:0)
    at static root method.(Unknown Source)

        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.heap.ImageHeapScanner.onObjectReachable(ImageHeapScanner.java:618)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.heap.SVMImageHeapScanner.onObjectReachable(SVMImageHeapScanner.java:127)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.heap.ImageHeapScanner.lambda$markReachable$0(ImageHeapScanner.java:589)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:166)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:152)
        at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.compute(ForkJoinTask.java:1750)
        at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.compute(ForkJoinTask.java:1742)
        at java.base/java.util.concurrent.ForkJoinTask$InterruptibleTask.exec(ForkJoinTask.java:1659)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:511)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1450)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2019)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: An object of type 'org.tukaani.xz.IA64Options' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.

@laert-ll

Copy link
Copy Markdown
Contributor Author

@vivu001 Thanks for the the GraalVM test and the error output, I applied some changes, could you please test it again?

@vivu001

vivu001 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

I followed the testing instructions, including the optional Ruby branch rebase and end-to-end ide install ruby run, and everything works perfectly.

The 7z extraction path, progress reporting, and Ruby installation all behave as expected.
Great work on this feature 🎉.

@vivu001 vivu001 moved this from Team Review to 👀 In review in IDEasy board Jul 23, 2026
@laert-ll
laert-ll requested a review from hohwille July 23, 2026 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request install installation process of IDE + tools and install commandlet

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

Add 7z archive extraction support

3 participants