Uploaded image for project: 'JBoss Enterprise Application Platform'
  1. JBoss Enterprise Application Platform
  2. JBEAP-27356

[GSS](8.0.z) Applying update fails when JBoss EAP installation directory (JBOSS_HOME) is symbolic link

    • False
    • None
    • False
    • Hide

      Apply update with Installation Manager (jboss-eap-installation-manager.sh) with specifying real path to "โ€“dir" option instead of specifying symbolic link. 

      Show
      Apply update with Installation Manager (jboss-eap-installation-manager.sh) with specifying real path to "โ€“dir" option instead of specifying symbolic link. 
    • Hide

      1. Install EAP 8.0.0 by extracting distribution zip

      $ cd /opt/
      $ unzip jboss-eap-8.0.0.zip
      

      2. Create a symbolic link

      $ ln -s /opt/jboss-eap-8.0 /opt/jboss8
      

      3. Apply update. For example, 8.0.2 (CP2)

      • JBoss-CLI:
        $ cd /opt/jboss8
        $ ./bin/standalone.sh
        
        $ ./bin/jboss-cli.sh -c --commands='installer update --maven-repo-files=/path/to/jboss-eap-8.0.2-maven-repository.zip --confirm, shutdown --perform-installation'
        

      or

      • Installation Manager:
        $ cd /opt/
        $ unzip jboss-eap-8.0.2-installation-manager.zip
        $ cd /opt/jboss-eap-installation-manager-8.0/
        $ ./bin/jboss-eap-installation-manager.sh update perform --dir=/opt/jboss8 
        

        Note: If you execute "./bin/jboss-eap-installation-manager.sh" under your JBoss Installation directory (JBOSS_HOME) and invoke "update perform" without "--dir" option, the issue does not happens

      4. You will see the following ERROR at the last step of applying update

      • With JBoss-CLI, no error in server.log and JBoss-CLI but the following ERROR is output in the console of running server:
        09:43:17,823 INFO  [org.wildfly.prospero] (main) PRSP000025: Applying update candidate from /opt/jboss8/standalone/tmp/installation-manager/prepared-server
        09:43:17,989 INFO  [org.wildfly.prospero] (main) PRSP000026: Changed artifacts [[MODIFIED] ...(snip)...
        
        ERROR: java.nio.file.FileAlreadyExistsException: /opt/jboss8
        ERROR: The operation was unsuccessful. The candidate server was not installed correctly.
        INFO: Restarting...
        09:43:24,822 INFO  [org.jboss.modules] (main) JBoss Modules version 2.1.0.Final-redhat-00001  // <-- jboss-modules.jar is not updated and still old version.
        09:43:25,595 INFO  [org.jboss.msc] (main) JBoss MSC version 1.5.1.Final-redhat-00001
        09:43:25,609 INFO  [org.jboss.threads] (main) JBoss Threads version 2.4.0.Final-redhat-00001
        09:43:25,797 INFO  [org.jboss.as] (MSC service thread 1-3) WFLYSRV0049: JBoss EAP 8.0 Update 2.0 (WildFly Core 21.0.9.Final-redhat-00001) starting // <-- However, CP2 has been apparently applied...
        
      • With Installation Manager, no error in logs/installation.log but only the following ERROR is output in the console of jboss-eap-installation-manager.sh:
        ERROR: java.nio.file.FileAlreadyExistsException: /opt/jboss8
        

      5. Patch history does not show the update applied

      $ ./bin/jboss-cli.sh -c --commands='installer history'
      [3268b557] 2024-01-19T09:04:16Z - install [org.jboss.eap.channels:eap-8.0::1.0.1.GA-redhat-00003]
      
      $ ./bin/jboss-eap-installation-manager.sh history --dir=/opt/jboss8
      [3268b557] 2024-01-19T09:04:16Z - install [org.jboss.eap.channels:eap-8.0::1.0.1.GA-redhat-00003]
      

      6. You will see the following ERROR when starting "embed-server" in JBoss-CLI:

      $ ./bin/jboss-cli.sh 
      You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
      [disconnected /] embed-server 
      org/jboss/modules/ModuleLoggerFinder: org.jboss.modules.ModuleLoggerFinder from [Module "org.wildfly.embedded" version 21.0.9.Final-redhat-00001 fr
      om local module loader @3a1a3f52 (finder: local module finder @7177ab38 (roots: /opt/jboss8/modules,/opt/jboss8/modules/system/layers/base))]
      
      Show
      1. Install EAP 8.0.0 by extracting distribution zip $ cd /opt/ $ unzip jboss-eap-8.0.0.zip 2. Create a symbolic link $ ln -s /opt/jboss-eap-8.0 /opt/jboss8 3. Apply update. For example, 8.0.2 (CP2) JBoss-CLI: $ cd /opt/jboss8 $ ./bin/standalone.sh $ ./bin/jboss-cli.sh -c --commands= 'installer update --maven-repo-files=/path/to/jboss-eap-8.0.2-maven-repository.zip --confirm, shutdown --perform-installation' or Installation Manager: $ cd /opt/ $ unzip jboss-eap-8.0.2-installation-manager.zip $ cd /opt/jboss-eap-installation-manager-8.0/ $ ./bin/jboss-eap-installation-manager.sh update perform --dir=/opt/jboss8 Note: If you execute "./bin/jboss-eap-installation-manager.sh" under your JBoss Installation directory (JBOSS_HOME) and invoke "update perform" without "--dir" option, the issue does not happens 4. You will see the following ERROR at the last step of applying update With JBoss-CLI, no error in server.log and JBoss-CLI but the following ERROR is output in the console of running server: 09:43:17,823 INFO [org.wildfly.prospero] (main) PRSP000025: Applying update candidate from /opt/jboss8/standalone/tmp/installation-manager/prepared-server 09:43:17,989 INFO [org.wildfly.prospero] (main) PRSP000026: Changed artifacts [[MODIFIED] ...(snip)... ERROR: java.nio.file.FileAlreadyExistsException: /opt/jboss8 ERROR: The operation was unsuccessful. The candidate server was not installed correctly. INFO: Restarting... 09:43:24,822 INFO [org.jboss.modules] (main) JBoss Modules version 2.1.0.Final-redhat-00001 // <-- jboss-modules.jar is not updated and still old version. 09:43:25,595 INFO [org.jboss.msc] (main) JBoss MSC version 1.5.1.Final-redhat-00001 09:43:25,609 INFO [org.jboss.threads] (main) JBoss Threads version 2.4.0.Final-redhat-00001 09:43:25,797 INFO [org.jboss.as] (MSC service thread 1-3) WFLYSRV0049: JBoss EAP 8.0 Update 2.0 (WildFly Core 21.0.9.Final-redhat-00001) starting // <-- However, CP2 has been apparently applied... With Installation Manager, no error in logs/installation.log but only the following ERROR is output in the console of jboss-eap-installation-manager.sh: ERROR: java.nio.file.FileAlreadyExistsException: /opt/jboss8 5. Patch history does not show the update applied $ ./bin/jboss-cli.sh -c --commands= 'installer history' [3268b557] 2024-01-19T09:04:16Z - install [org.jboss.eap.channels:eap-8.0::1.0.1.GA-redhat-00003] $ ./bin/jboss-eap-installation-manager.sh history --dir=/opt/jboss8 [3268b557] 2024-01-19T09:04:16Z - install [org.jboss.eap.channels:eap-8.0::1.0.1.GA-redhat-00003] 6. You will see the following ERROR when starting "embed-server" in JBoss-CLI: $ ./bin/jboss-cli.sh You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands. [disconnected /] embed-server org/jboss/modules/ModuleLoggerFinder: org.jboss.modules.ModuleLoggerFinder from [Module "org.wildfly.embedded" version 21.0.9.Final-redhat-00001 fr om local module loader @3a1a3f52 (finder: local module finder @7177ab38 (roots: /opt/jboss8/modules,/opt/jboss8/modules/system/layers/base))]

      When specified JBoss EAP 8.x installation directory (JBOSS_HOME) is a symbolic link, applying update fails with "ERROR: java.nio.file.FileAlreadyExistsException: <specified-path-of-JBOSS_HOME-directory>".

      This issue can happen with whether JBoss-CLI ("installer update" and "shutdown -perform-installation") or jboss-eap-installation-manager.sh (invoke "update perform" along with setting "-dir" option).
      (Note: If you use "JBOSS_HOME/bin/jboss-eap-installation-manager.sh" of your JBoss Installation directory and execute "./bin/jboss-eap-installation-manager.sh update perform" under JBOSS_HOME directory without setting "--dir" option , the issue luckily does not happen.)

      Actually, it fails only at the last part of applying updates (copying jboss-modules.jar), so other files under modules directory are appearantly updated succeessfully before the ERROR message.

      This results in the following incosistent state of installation:

      • The version information output of "./bin/standalone.sh --verion" says "JBoss EAP 8.0.2"
        (Even if applying update stopped with the ERROR message and not completed correctly, the version shows newer version.)
      • The output of "installer history" in JBoss-CLI or "./bin/jboss-eap-installation-manager.sh history" do not show update history.
      • $JBOSS_HOME/jboss-modules.jar is not updated, so the following ERROR can happen when starting "embed-server" in JBoss-CLI in JBoss EAP 8.0.2. Because "org.jboss.modules.ModuleLoggerFinder" only exists in newer versions of jboss-modules.jar included in JBoss EAP 8.0.2+ and some modules (like "embed-server") depends on it.
      $ ./bin/jboss-cli.sh 
      You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
      [disconnected /] embed-server 
      org/jboss/modules/ModuleLoggerFinder: org.jboss.modules.ModuleLoggerFinder from [Module "org.wildfly.embedded" version 21.0.9.Final-redhat-00001 fr
      om local module loader @3a1a3f52 (finder: local module finder @7177ab38 (roots: /opt/jboss8/modules,/opt/jboss8/modules/system/layers/base))]
      

            [JBEAP-27356] [GSS](8.0.z) Applying update fails when JBoss EAP installation directory (JBOSS_HOME) is symbolic link

            Errata Tool added a comment -

            Since the problem described in this issue should be resolved in a recent advisory, it has been closed.

            For information on the advisory (Important: Red Hat JBoss Enterprise Application Platform 8.0.3 Security update), and where to find the updated files, follow the link below.

            If the solution does not work for you, open a new bug report.
            https://access.redhat.com/errata/RHSA-2024:5481

            Errata Tool added a comment - Since the problem described in this issue should be resolved in a recent advisory, it has been closed. For information on the advisory (Important: Red Hat JBoss Enterprise Application Platform 8.0.3 Security update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHSA-2024:5481

            Errata Tool added a comment -

            Since the problem described in this issue should be resolved in a recent advisory, it has been closed.

            For information on the advisory (Important: Red Hat JBoss Enterprise Application Platform 8.0.3 Security update), and where to find the updated files, follow the link below.

            If the solution does not work for you, open a new bug report.
            https://access.redhat.com/errata/RHSA-2024:5479

            Errata Tool added a comment - Since the problem described in this issue should be resolved in a recent advisory, it has been closed. For information on the advisory (Important: Red Hat JBoss Enterprise Application Platform 8.0.3 Security update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHSA-2024:5479

            Errata Tool added a comment -

            Since the problem described in this issue should be resolved in a recent advisory, it has been closed.

            For information on the advisory (Important: Red Hat JBoss Enterprise Application Platform 8.0.3 Security update), and where to find the updated files, follow the link below.

            If the solution does not work for you, open a new bug report.
            https://access.redhat.com/errata/RHSA-2024:5482

            Errata Tool added a comment - Since the problem described in this issue should be resolved in a recent advisory, it has been closed. For information on the advisory (Important: Red Hat JBoss Enterprise Application Platform 8.0.3 Security update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHSA-2024:5482

            I would like to propose the following two change to fix this issue. Either of the following can resolve the issue, but I would suggest incroporating both.

            For Prospero: add if checking symbolic link and obtain real path if the specified path is symbolic link

            https://github.com/wildfly-extras/prospero/compare/1.1.x...msfm:prospero:1.1.x_JBEAP-27356

            diff --git a/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java b/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java
            index f1d79a1..37f3a3a 100644
            --- a/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java
            +++ b/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java
            @@ -18,6 +18,7 @@
             package org.wildfly.prospero.cli.commands;
             
             import java.io.File;
            +import java.io.IOException;
             import java.nio.file.Files;
             import java.nio.file.Path;
             import java.nio.file.Paths;
            @@ -68,6 +69,17 @@ public abstract class AbstractCommand implements Callable<Integer> {
             
                 protected static Path determineInstallationDirectory(Optional<Path> directoryOption) throws ArgumentParsingException {
                     Path installationDirectory = directoryOption.orElse(currentDir()).toAbsolutePath();
            +        if (Files.isSymbolicLink(installationDirectory)) {
            +            // if installationDirectory is symbolic link, obtain real path
            +            try {
            +                installationDirectory = installationDirectory.toRealPath();
            +            } catch (IOException e) {
            +                throw new ArgumentParsingException("Target server path " + installationDirectory + " is symbolic link, but the real path doesn't exist (or I/O error occurred)", e);
            +            }
            +        }
            +        if (!Files.isDirectory(installationDirectory)) {
            +            throw new ArgumentParsingException("Target server path [" + installationDirectory + "] is not directory");
            +        }
                     verifyDirectoryContainsInstallation(installationDirectory);
                     return installationDirectory;
                 }
            

            For Galleon IoUtils, add exception handling when FileAlreadyExistsException happens at Files.createDirectories() and ignore it if the existing symbolic link is directory.

            https://github.com/wildfly/galleon/compare/5.1.x...msfm:galleon:5.1.x_JBEAP-27356

            diff --git a/core/src/main/java/org/jboss/galleon/util/IoUtils.java b/core/src/main/java/org/jboss/galleon/util/IoUtils.java
            index 6049fb3..f459048 100644
            --- a/core/src/main/java/org/jboss/galleon/util/IoUtils.java
            +++ b/core/src/main/java/org/jboss/galleon/util/IoUtils.java
            @@ -152,10 +152,26 @@ public class IoUtils {
                 }
             
                 public static void copy(Path source, Path target, boolean skipExistingFiles) throws IOException {
            -        if(Files.isDirectory(source)) {
            -            Files.createDirectories(target);
            +        if (Files.isDirectory(source)) {
            +            try {
            +                Files.createDirectories(target);
            +            } catch (FileAlreadyExistsException e) {
            +                // FileAlreadyExistsException happen if the target path already exists and it's not directly (symbolic link or regular file)
            +                // this exception can be ignored if it's symbolic link and if real path of the symbolic link is directory.
            +                if (!Files.isDirectory(target)) {
            +                    throw new IOException("Unable to copy file(s) from source path [" + source + "] to target path [" + target + "] because the target path is not directory (regular file or symbolic link where real path is not directory).", e);
            +                }
            +            }
                     } else {
            -            Files.createDirectories(target.getParent());
            +            try {
            +                Files.createDirectories(target.getParent());
            +            } catch (FileAlreadyExistsException e) {
            +                // FileAlreadyExistsException happen if the target path already exists and it's not directly (symbolic link or regular file)
            +                // this exception can be ignored if it's symbolic link and if real path of the symbolic link is directory.
            +                if (!Files.isDirectory(target.getParent())) {
            +                    throw new IOException("Unable to copy file(s) from source path [" + source + "] to target path [" + target + "] because parent directory of the target path is not directory (regular file or symbolic link where real path is not directory).", e);
            +                }
            +            }
                     }
                     Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
                             new SimpleFileVisitor<Path>() {
            

            Masafumi Miura added a comment - I would like to propose the following two change to fix this issue. Either of the following can resolve the issue, but I would suggest incroporating both. For Prospero: add if checking symbolic link and obtain real path if the specified path is symbolic link https://github.com/wildfly-extras/prospero/compare/1.1.x...msfm:prospero:1.1.x_JBEAP-27356 diff --git a/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java b/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java index f1d79a1..37f3a3a 100644 --- a/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java +++ b/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java @@ -18,6 +18,7 @@ package org.wildfly.prospero.cli.commands; import java.io.File; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -68,6 +69,17 @@ public abstract class AbstractCommand implements Callable< Integer > { protected static Path determineInstallationDirectory(Optional<Path> directoryOption) throws ArgumentParsingException { Path installationDirectory = directoryOption.orElse(currentDir()).toAbsolutePath(); + if (Files.isSymbolicLink(installationDirectory)) { + // if installationDirectory is symbolic link, obtain real path + try { + installationDirectory = installationDirectory.toRealPath(); + } catch (IOException e) { + throw new ArgumentParsingException( "Target server path " + installationDirectory + " is symbolic link, but the real path doesn't exist (or I/O error occurred)" , e); + } + } + if (!Files.isDirectory(installationDirectory)) { + throw new ArgumentParsingException( "Target server path [" + installationDirectory + "] is not directory" ); + } verifyDirectoryContainsInstallation(installationDirectory); return installationDirectory; } For Galleon IoUtils, add exception handling when FileAlreadyExistsException happens at Files.createDirectories() and ignore it if the existing symbolic link is directory. https://github.com/wildfly/galleon/compare/5.1.x...msfm:galleon:5.1.x_JBEAP-27356 diff --git a/core/src/main/java/org/jboss/galleon/util/IoUtils.java b/core/src/main/java/org/jboss/galleon/util/IoUtils.java index 6049fb3..f459048 100644 --- a/core/src/main/java/org/jboss/galleon/util/IoUtils.java +++ b/core/src/main/java/org/jboss/galleon/util/IoUtils.java @@ -152,10 +152,26 @@ public class IoUtils { } public static void copy(Path source, Path target, boolean skipExistingFiles) throws IOException { - if (Files.isDirectory(source)) { - Files.createDirectories(target); + if (Files.isDirectory(source)) { + try { + Files.createDirectories(target); + } catch (FileAlreadyExistsException e) { + // FileAlreadyExistsException happen if the target path already exists and it's not directly (symbolic link or regular file) + // this exception can be ignored if it's symbolic link and if real path of the symbolic link is directory. + if (!Files.isDirectory(target)) { + throw new IOException( "Unable to copy file(s) from source path [" + source + "] to target path [" + target + "] because the target path is not directory (regular file or symbolic link where real path is not directory)." , e); + } + } } else { - Files.createDirectories(target.getParent()); + try { + Files.createDirectories(target.getParent()); + } catch (FileAlreadyExistsException e) { + // FileAlreadyExistsException happen if the target path already exists and it's not directly (symbolic link or regular file) + // this exception can be ignored if it's symbolic link and if real path of the symbolic link is directory. + if (!Files.isDirectory(target.getParent())) { + throw new IOException( "Unable to copy file(s) from source path [" + source + "] to target path [" + target + "] because parent directory of the target path is not directory (regular file or symbolic link where real path is not directory)." , e); + } + } } Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer .MAX_VALUE, new SimpleFileVisitor<Path>() {

            Masafumi Miura added a comment - - edited

            The ERROR message does not show stack trace.

            I captured all of FileAlreadyExistsException by the following byteman rule:

            RULE FileAlreadyExistsException_init
            CLASS java.nio.file.FileAlreadyExistsException
            METHOD <init>
            AT ENTRY
            DO
            traceStack("-------------- java.nio.file.FileAlreadyExistsException is initiallized. file = " + $1 + "\n");
            ENDRULE
            

            then, the above byteman rule can show it was thrown at "Files.createDirectories()" invocation in org.jboss.galleon.util.IoUtils#copy().

            Also, you can use the following byteman rule to capture the details of stack trace:

            RULE org.jboss.galleon.util.IoUtils_copy_EXCEPTION_EXIT
            CLASS org.jboss.galleon.util.IoUtils
            METHOD copy
            AT EXCEPTION EXIT
            IF TRUE
            DO
                traceStack("-------------- org.jboss.galleon.util.IoUtils#copy() exit with exception.\n source path = [" + $1 + "]\n target path = [" + $2 + "]\n thrown exception = " + $^ + "\n\n");
                $^.printStackTrace();
            ENDRULE
            

            The above byteman rule can show output like the following:

            -------------- org.jboss.galleon.util.IoUtils#copy() exit with exception.
             source path = [/tmp/update-candidate9535441453771860017/jboss-modules.jar]
             target path = [/opt/jboss8/jboss-modules.jar]
             thrown exception = java.nio.file.FileAlreadyExistsException: /opt/jboss8
            
            org.jboss.galleon.util.IoUtils.copy(IoUtils.java:152)
            org.wildfly.prospero.actions.ApplyCandidateAction$1.visitFile(ApplyCandidateAction.java:588)
            org.wildfly.prospero.actions.ApplyCandidateAction$1.visitFile(ApplyCandidateAction.java:572)
            java.nio.file.Files.walkFileTree(Files.java:2725)
            java.nio.file.Files.walkFileTree(Files.java:2797)
            org.wildfly.prospero.actions.ApplyCandidateAction.doApplyUpdate(ApplyCandidateAction.java:572)
            org.wildfly.prospero.actions.ApplyCandidateAction.applyUpdate(ApplyCandidateAction.java:164)
            org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.performUpdate(UpdateCommand.java:130)
            org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.call(UpdateCommand.java:102)
            org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.call(UpdateCommand.java:63)
            picocli.CommandLine.executeUserObject(CommandLine.java:2041)
            picocli.CommandLine.access$1500(CommandLine.java:148)
            picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2461)
            picocli.CommandLine$RunLast.handle(CommandLine.java:2453)
            picocli.CommandLine$RunLast.handle(CommandLine.java:2415)
            picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2273)
            picocli.CommandLine$RunLast.execute(CommandLine.java:2417)
            picocli.CommandLine.execute(CommandLine.java:2170)
            org.wildfly.prospero.cli.CliMain.main(CliMain.java:62)
            org.jboss.modules.Module.run(Module.java:346)
            org.jboss.modules.Module.run(Module.java:314)
            org.jboss.modules.Main.main(Main.java:603)
            java.nio.file.FileAlreadyExistsException: /opt/jboss8
            	at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:94)
            	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
            	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
            	at java.base/sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:389)
            	at java.base/java.nio.file.Files.createDirectory(Files.java:690)
            	at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:797)
            	at java.base/java.nio.file.Files.createDirectories(Files.java:743)
            	at org.jboss.prospero//org.jboss.galleon.util.IoUtils.copy(IoUtils.java:158)
            	at org.jboss.prospero//org.jboss.galleon.util.IoUtils.copy(IoUtils.java:151)
            	at org.jboss.prospero//org.wildfly.prospero.actions.ApplyCandidateAction$1.visitFile(ApplyCandidateAction.java:588)
            	at org.jboss.prospero//org.wildfly.prospero.actions.ApplyCandidateAction$1.visitFile(ApplyCandidateAction.java:572)
            	at java.base/java.nio.file.Files.walkFileTree(Files.java:2725)
            	at java.base/java.nio.file.Files.walkFileTree(Files.java:2797)
            	at org.jboss.prospero//org.wildfly.prospero.actions.ApplyCandidateAction.doApplyUpdate(ApplyCandidateAction.java:572)
            	at org.jboss.prospero//org.wildfly.prospero.actions.ApplyCandidateAction.applyUpdate(ApplyCandidateAction.java:164)
            	at org.jboss.prospero//org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.performUpdate(UpdateCommand.java:130)
            	at org.jboss.prospero//org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.call(UpdateCommand.java:102)
            	at org.jboss.prospero//org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.call(UpdateCommand.java:63)
            	at org.jboss.prospero//picocli.CommandLine.executeUserObject(CommandLine.java:2041)
            	at org.jboss.prospero//picocli.CommandLine.access$1500(CommandLine.java:148)
            	at org.jboss.prospero//picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2461)
            	at org.jboss.prospero//picocli.CommandLine$RunLast.handle(CommandLine.java:2453)
            	at org.jboss.prospero//picocli.CommandLine$RunLast.handle(CommandLine.java:2415)
            	at org.jboss.prospero//picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2273)
            	at org.jboss.prospero//picocli.CommandLine$RunLast.execute(CommandLine.java:2417)
            	at org.jboss.prospero//picocli.CommandLine.execute(CommandLine.java:2170)
            	at org.jboss.prospero//org.wildfly.prospero.cli.CliMain.main(CliMain.java:62)
            	at org.jboss.modules.Module.run(Module.java:346)
            	at org.jboss.modules.Module.run(Module.java:314)
            	at org.jboss.modules.Main.main(Main.java:603)
            

            So, "Files.createDirectories(target.getParent());" fails with FileAlreadyExistsException when the path is symbolic link in org.jboss.galleon.util.IoUtils#copy():

            https://github.com/wildfly/galleon/blob/5.1.2.Final/core/src/main/java/org/jboss/galleon/util/IoUtils.java#L158

            Note that "--dir" option is not specified to "jboss-eap-installation-manager.sh", the target path is obtain from "Paths.get(".").toAbsolutePath();" and this does not return the real path instead of path containing symbolic link. So, the issue does not happen luckily.

            https://github.com/wildfly-extras/prospero/blob/1.1.11.Final/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java#L70
            https://github.com/wildfly-extras/prospero/blob/1.1.11.Final/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java#L90-L92

            Masafumi Miura added a comment - - edited The ERROR message does not show stack trace. I captured all of FileAlreadyExistsException by the following byteman rule: RULE FileAlreadyExistsException_init CLASS java.nio.file.FileAlreadyExistsException METHOD <init> AT ENTRY DO traceStack( "-------------- java.nio.file.FileAlreadyExistsException is initiallized. file = " + $1 + "\n" ); ENDRULE then, the above byteman rule can show it was thrown at "Files.createDirectories()" invocation in org.jboss.galleon.util.IoUtils#copy(). Also, you can use the following byteman rule to capture the details of stack trace: RULE org.jboss.galleon.util.IoUtils_copy_EXCEPTION_EXIT CLASS org.jboss.galleon.util.IoUtils METHOD copy AT EXCEPTION EXIT IF TRUE DO traceStack( "-------------- org.jboss.galleon.util.IoUtils#copy() exit with exception.\n source path = [" + $1 + "]\n target path = [" + $2 + "]\n thrown exception = " + $^ + "\n\n" ); $^.printStackTrace(); ENDRULE The above byteman rule can show output like the following: -------------- org.jboss.galleon.util.IoUtils#copy() exit with exception. source path = [/tmp/update-candidate9535441453771860017/jboss-modules.jar] target path = [/opt/jboss8/jboss-modules.jar] thrown exception = java.nio.file.FileAlreadyExistsException: /opt/jboss8 org.jboss.galleon.util.IoUtils.copy(IoUtils.java:152) org.wildfly.prospero.actions.ApplyCandidateAction$1.visitFile(ApplyCandidateAction.java:588) org.wildfly.prospero.actions.ApplyCandidateAction$1.visitFile(ApplyCandidateAction.java:572) java.nio.file.Files.walkFileTree(Files.java:2725) java.nio.file.Files.walkFileTree(Files.java:2797) org.wildfly.prospero.actions.ApplyCandidateAction.doApplyUpdate(ApplyCandidateAction.java:572) org.wildfly.prospero.actions.ApplyCandidateAction.applyUpdate(ApplyCandidateAction.java:164) org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.performUpdate(UpdateCommand.java:130) org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.call(UpdateCommand.java:102) org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.call(UpdateCommand.java:63) picocli.CommandLine.executeUserObject(CommandLine.java:2041) picocli.CommandLine.access$1500(CommandLine.java:148) picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2461) picocli.CommandLine$RunLast.handle(CommandLine.java:2453) picocli.CommandLine$RunLast.handle(CommandLine.java:2415) picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2273) picocli.CommandLine$RunLast.execute(CommandLine.java:2417) picocli.CommandLine.execute(CommandLine.java:2170) org.wildfly.prospero.cli.CliMain.main(CliMain.java:62) org.jboss.modules.Module.run(Module.java:346) org.jboss.modules.Module.run(Module.java:314) org.jboss.modules.Main.main(Main.java:603) java.nio.file.FileAlreadyExistsException: /opt/jboss8 at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:94) at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116) at java.base/sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:389) at java.base/java.nio.file.Files.createDirectory(Files.java:690) at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:797) at java.base/java.nio.file.Files.createDirectories(Files.java:743) at org.jboss.prospero //org.jboss.galleon.util.IoUtils.copy(IoUtils.java:158) at org.jboss.prospero //org.jboss.galleon.util.IoUtils.copy(IoUtils.java:151) at org.jboss.prospero //org.wildfly.prospero.actions.ApplyCandidateAction$1.visitFile(ApplyCandidateAction.java:588) at org.jboss.prospero //org.wildfly.prospero.actions.ApplyCandidateAction$1.visitFile(ApplyCandidateAction.java:572) at java.base/java.nio.file.Files.walkFileTree(Files.java:2725) at java.base/java.nio.file.Files.walkFileTree(Files.java:2797) at org.jboss.prospero //org.wildfly.prospero.actions.ApplyCandidateAction.doApplyUpdate(ApplyCandidateAction.java:572) at org.jboss.prospero //org.wildfly.prospero.actions.ApplyCandidateAction.applyUpdate(ApplyCandidateAction.java:164) at org.jboss.prospero //org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.performUpdate(UpdateCommand.java:130) at org.jboss.prospero //org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.call(UpdateCommand.java:102) at org.jboss.prospero //org.wildfly.prospero.cli.commands.UpdateCommand$PerformCommand.call(UpdateCommand.java:63) at org.jboss.prospero //picocli.CommandLine.executeUserObject(CommandLine.java:2041) at org.jboss.prospero //picocli.CommandLine.access$1500(CommandLine.java:148) at org.jboss.prospero //picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2461) at org.jboss.prospero //picocli.CommandLine$RunLast.handle(CommandLine.java:2453) at org.jboss.prospero //picocli.CommandLine$RunLast.handle(CommandLine.java:2415) at org.jboss.prospero //picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2273) at org.jboss.prospero //picocli.CommandLine$RunLast.execute(CommandLine.java:2417) at org.jboss.prospero //picocli.CommandLine.execute(CommandLine.java:2170) at org.jboss.prospero //org.wildfly.prospero.cli.CliMain.main(CliMain.java:62) at org.jboss.modules.Module.run(Module.java:346) at org.jboss.modules.Module.run(Module.java:314) at org.jboss.modules.Main.main(Main.java:603) So, "Files.createDirectories(target.getParent());" fails with FileAlreadyExistsException when the path is symbolic link in org.jboss.galleon.util.IoUtils#copy(): https://github.com/wildfly/galleon/blob/5.1.2.Final/core/src/main/java/org/jboss/galleon/util/IoUtils.java#L158 Note that "--dir" option is not specified to "jboss-eap-installation-manager.sh", the target path is obtain from "Paths.get(".").toAbsolutePath();" and this does not return the real path instead of path containing symbolic link. So, the issue does not happen luckily. https://github.com/wildfly-extras/prospero/blob/1.1.11.Final/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java#L70 https://github.com/wildfly-extras/prospero/blob/1.1.11.Final/prospero-cli/src/main/java/org/wildfly/prospero/cli/commands/AbstractCommand.java#L90-L92

              spyrkob Bartosz Spyrko-Smietanko
              rhn-support-mmiura Masafumi Miura
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

                Created:
                Updated:
                Resolved: