glassfish
  1. glassfish
  2. GLASSFISH-18789

Cannot enable versioned application on Windows

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.1.2
    • Fix Version/s: 4.1
    • Component/s: security
    • Labels:
      None
    • Environment:

      Windows XP, Windows 7, Windows 2008 R2

      Description

      Attempt to enable versioned application containing EJBs on windows platform fails with following exception:

      asadmin enable --target inst1 test:v1
      remote failure: An error occurred during replication
      Failure: Command enable failed on server instance inst1:
        remote failure: Exception while loading the app
      Error in committing security policy for ejbs of test:v1 
      -- javax.security.jacc.PolicyContextException: java.io.FileNotFoundException:
      ...\glassfish3\glassfish\nodes\localhost-domain1\inst1\generated\policy\test:v1\test_v1_internal\granted.policy 
      (The filename, directory name, or volume label syntax is incorrect)
      Command enable failed.
      

      Steps to reproduce:

      1. start domain1
      2. set PATH=<path to asadmin>;%PATH%
      3. run attached test.cmd. It will
        • create new instance
        • deploy the war file as test:v1
        • execute asadmin enable --target inst1 test:v1

        Issue Links

          Activity

          Hide
          pdudits added a comment -

          Also verified with 4.0_b39

          Show
          pdudits added a comment - Also verified with 4.0_b39
          Hide
          Jeremy_Lv added a comment - - edited

          I have reappeared this issue again, the issue is occured by the name with the symbol like ":". Although the application can be named as "test:v1" during the command, the file test:v1 can't be created on the environment of windows because of the illegal symbol ":".

          However, you will found the file in the directory GF_home\glassfish\domains\domain1\applications called "test~v1" but not the "test:v1".

          Because of the different name with the application and the file created in the directory GF_home\glassfish\domains\domain1\applications. the error messages are thrown out.

          [My idea]
          I have some revised idea about it.
          when deploying the application on the environment of windows, we can check the name about the application whether it contains the similar illegal symbols like "\/:*?"<>|" and throw out Exception to tell user it contains the illegal symbols so that the user can select the other name.

          Dear Hong:
          Does my revised idea available to this issue?

          Show
          Jeremy_Lv added a comment - - edited I have reappeared this issue again, the issue is occured by the name with the symbol like ":". Although the application can be named as "test:v1" during the command, the file test:v1 can't be created on the environment of windows because of the illegal symbol ":". However, you will found the file in the directory GF_home\glassfish\domains\domain1\applications called "test~v1" but not the "test:v1". Because of the different name with the application and the file created in the directory GF_home\glassfish\domains\domain1\applications. the error messages are thrown out. [My idea] I have some revised idea about it. when deploying the application on the environment of windows, we can check the name about the application whether it contains the similar illegal symbols like "\/:*?"<>|" and throw out Exception to tell user it contains the illegal symbols so that the user can select the other name. Dear Hong: Does my revised idea available to this issue?
          Hide
          Jeremy_Lv added a comment -

          when you deploy this war with diable option, the logical operation like loading the app hadn't been checked.

          However, if you deploy the application with enable opition.the warming messages will thrown out as follows:
          WARNING: Command _deploy did not complete successfully on server instance inst1:
          remote failure: Failed to load the application on instance inst1. The applicati
          on will not run properly. Please fix your application and redeploy.
          Exception while loading the app : Error in committing security policy for ejbs o
          f test:v1 – javax.security.jacc.PolicyContextException: java.lang.RuntimeExcept
          ion: unable to create policy context directory. Please see server.log for more d
          etails.
          Command deploy completed with warnings.

          I think ApplicationInfo#load and ApplicationLifecycle#deploy and PolicyConfigurationImpl#createPolicyContextDirectory may be useful for me to revised this issue.

          Show
          Jeremy_Lv added a comment - when you deploy this war with diable option, the logical operation like loading the app hadn't been checked. However, if you deploy the application with enable opition.the warming messages will thrown out as follows: WARNING: Command _deploy did not complete successfully on server instance inst1: remote failure: Failed to load the application on instance inst1. The applicati on will not run properly. Please fix your application and redeploy. Exception while loading the app : Error in committing security policy for ejbs o f test:v1 – javax.security.jacc.PolicyContextException: java.lang.RuntimeExcept ion: unable to create policy context directory. Please see server.log for more d etails. Command deploy completed with warnings. I think ApplicationInfo#load and ApplicationLifecycle#deploy and PolicyConfigurationImpl#createPolicyContextDirectory may be useful for me to revised this issue.
          Hide
          Jeremy_Lv added a comment -

          The similar situation can be reappeared when deployed on server because of the illegal symbol ":".

          Show
          Jeremy_Lv added a comment - The similar situation can be reappeared when deployed on server because of the illegal symbol ":".
          Hide
          pdudits added a comment -

          when deploying the application on the environment of windows, we can check the name about the application whether it contains the similar illegal symbols like "\/:*?"<>|" and throw out Exception to tell user it contains the illegal symbols so that the user can select the other name.

          Jeremy, this would of course mean, that application versioning feature is not supported on windows, and that needs to be explicitly stated in documentation.

          So likely implementing same substitution in PolicyConfigurationFacoryImpl#getContextDirectoryName like the one that applies to application name is the way to go.

          Show
          pdudits added a comment - when deploying the application on the environment of windows, we can check the name about the application whether it contains the similar illegal symbols like "\/:*?"<>|" and throw out Exception to tell user it contains the illegal symbols so that the user can select the other name. Jeremy, this would of course mean, that application versioning feature is not supported on windows, and that needs to be explicitly stated in documentation. So likely implementing same substitution in PolicyConfigurationFacoryImpl#getContextDirectoryName like the one that applies to application name is the way to go.
          Hide
          Jeremy_Lv added a comment - - edited

          Dear pdudits :

          [My opition]
          I think I should check the appname in ApplicationLifecycle#deploy whether it contains the illegal
          symbols like "\/:*?"<>|".
          If it contains these symbols, I think the deploy operation should be failed in deployment on the environment of windows. Then GF should throw out the exception about the reason of deploying failed.

          I'm modifing the resource in my own computer now and it'll be fine soon.

          However, I think we should discuss the final solution with Hong Zhang.

          Show
          Jeremy_Lv added a comment - - edited Dear pdudits : [My opition] I think I should check the appname in ApplicationLifecycle#deploy whether it contains the illegal symbols like "\/:*?"<>|". If it contains these symbols, I think the deploy operation should be failed in deployment on the environment of windows. Then GF should throw out the exception about the reason of deploying failed. I'm modifing the resource in my own computer now and it'll be fine soon. However, I think we should discuss the final solution with Hong Zhang.
          Hide
          Jeremy_Lv added a comment - - edited

          I think it dangerous to deploy the application if the appname is different from the name of the directory.

          Show
          Jeremy_Lv added a comment - - edited I think it dangerous to deploy the application if the appname is different from the name of the directory.
          Hide
          Hong Zhang added a comment -

          Jeremy: The versioning feature needs to be supported on windows. This is either a regression or a scenario that we did not test before which should be fixed.

          It is expected that the repository name is "test~v1", we intentionally did that to not use illegal character in file path, see VersioningUtils.getRepositoryName. Yes it is tricky when the application name is different than the file path, and this bug is probably due to we forgot to handle it in some code path where it should.

          You should see how it works with deploy command today, and compare the difference with enable command to see what needs to be fixed.

          You can read more about the versioning feature here:
          https://wikis.oracle.com/display/GlassFish/ApplicationVersioning

          Show
          Hong Zhang added a comment - Jeremy: The versioning feature needs to be supported on windows. This is either a regression or a scenario that we did not test before which should be fixed. It is expected that the repository name is "test~v1", we intentionally did that to not use illegal character in file path, see VersioningUtils.getRepositoryName. Yes it is tricky when the application name is different than the file path, and this bug is probably due to we forgot to handle it in some code path where it should. You should see how it works with deploy command today, and compare the difference with enable command to see what needs to be fixed. You can read more about the versioning feature here: https://wikis.oracle.com/display/GlassFish/ApplicationVersioning
          Hide
          Jeremy_Lv added a comment -

          Thanks for your suggestions, I'll investigate it and try to revised it as soon as possible.

          Show
          Jeremy_Lv added a comment - Thanks for your suggestions, I'll investigate it and try to revised it as soon as possible.
          Hide
          Jeremy_Lv added a comment -

          Dear Hong, pdudits:
          I have fixed this issue and uploaded my patch file to the attachment. please check my code.

          the logical of this issue is as follows:
          1.The illegal symbol ":" about the variable called linkName doesn't changed to "~" when excute SecurityDeployer#linkPolicies:

            Set<EjbBundleDescriptor> ejbs = app.getBundleDescriptors(EjbBundleDescriptor.class);
            for (EjbBundleDescriptor ejbd : ejbs) {
                String name = SecurityUtil.getContextID(ejbd);
                lastInService =SecurityUtil.linkPolicyFile(name, linkName, lastInService);
                linkName = name;
            }
          

          2.the variable called contextDirectoryName got the illegal symbol ":" after the step1.

                  String contextDirectoryName = getContextDirectoryName();
                  File d = new File(contextDirectoryName);
          
                  String defMsg = "unable to create policy context directory";
                  String msg = localStrings.getLocalString("pc.unable_to_create_context_directory",
                          defMsg, new Object[]{contextDirectoryName});
                  if (d.exists()) {
                      if (!d.isDirectory()) {
          
                          logger.log(Level.SEVERE, msg);
                          throw new RuntimeException(defMsg);
                      }
                  } else {
                      if (!d.mkdirs()) {
                          logger.log(Level.SEVERE, msg);
                          throw new RuntimeException(defMsg);
                      }
          

          then the RuntimeException will be thrown out.

          Show
          Jeremy_Lv added a comment - Dear Hong, pdudits: I have fixed this issue and uploaded my patch file to the attachment. please check my code. the logical of this issue is as follows: 1.The illegal symbol ":" about the variable called linkName doesn't changed to "~" when excute SecurityDeployer#linkPolicies: Set<EjbBundleDescriptor> ejbs = app.getBundleDescriptors(EjbBundleDescriptor.class); for (EjbBundleDescriptor ejbd : ejbs) { String name = SecurityUtil.getContextID(ejbd); lastInService =SecurityUtil.linkPolicyFile(name, linkName, lastInService); linkName = name; } 2.the variable called contextDirectoryName got the illegal symbol ":" after the step1. String contextDirectoryName = getContextDirectoryName(); File d = new File(contextDirectoryName); String defMsg = "unable to create policy context directory" ; String msg = localStrings.getLocalString( "pc.unable_to_create_context_directory" , defMsg, new Object []{contextDirectoryName}); if (d.exists()) { if (!d.isDirectory()) { logger.log(Level.SEVERE, msg); throw new RuntimeException(defMsg); } } else { if (!d.mkdirs()) { logger.log(Level.SEVERE, msg); throw new RuntimeException(defMsg); } then the RuntimeException will be thrown out.
          Hide
          Jeremy_Lv added a comment -

          I have updated your web application because the <servlet-name> in web.xml isn't right when it comes to the latest version of GFV4.

          Show
          Jeremy_Lv added a comment - I have updated your web application because the <servlet-name> in web.xml isn't right when it comes to the latest version of GFV4.
          Hide
          Hong Zhang added a comment -

          Thanks Jeremy for looking into this. This same code path should be executed by the deploy command code path also (asadmin deploy), can you check why this code does not cause issue in that code path? This part of the code is quite tricky from my understanding, so we need to be extra careful about it. And as this part of the code is owned by the security team, any changes in this area will need to be reviewed by them and run the security dev tests also (in addition to Quicklook and deployment dev tests).

          Show
          Hong Zhang added a comment - Thanks Jeremy for looking into this. This same code path should be executed by the deploy command code path also (asadmin deploy), can you check why this code does not cause issue in that code path? This part of the code is quite tricky from my understanding, so we need to be extra careful about it. And as this part of the code is owned by the security team, any changes in this area will need to be reviewed by them and run the security dev tests also (in addition to Quicklook and deployment dev tests).
          Hide
          Jeremy_Lv added a comment - - edited

          Dear Hong:
          The related code in ApplicationLifecycle#deploy as follows:

                          if (loadOnCurrentInstance(context)) {
                              appInfo.setLibraries(commandParams.libraries());
                              try {
                                  notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.LOAD, context);
                                  appInfo.load(context, tracker);
                                  notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.LOAD, context);
                                  
                                  notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.START, context);
                                  appInfo.start(context, tracker);
                                  notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.START, context);
                              } catch(Throwable loadException) {
                                  logger.log(Level.SEVERE, loadException.getMessage(), loadException);
                                  report.failure(logger, "Exception while loading the app", null);
                                  report.setFailureCause(loadException);
                                  tracker.actOn(logger);
                                  return null;
                              }
                          }
          

          The code path can be excuted only if the value of "loadOnCurrentInstance(context)" in ApplicationLifecycle#deploy is true.
          For examples:
          1.(1)if you excute the command like "asadmin deploy --enabled false --target inst1 --name test:v1 versioning-test.war", you will found the code path can't be excuted because of the value of "loadOnCurrentInstance(context)" is false.
          (2)then excute as "asadmin enable --target inst1 test:v1", the error message like "java.lang.RuntimeException: unable to create policy context directory" is thrown out.
          2.However, if you excute the command like "asadmin deploy --target inst1 --name test:v1 versioning" with default value about enable the application, the application can be deployed but with some warning messages like "java.lang.RuntimeException: unable to create policy context directory" because the application has been loaded and then the code path has been excuted.

          Above all, the messages like "java.lang.RuntimeException: unable to create policy context directory" can be thrown out when you load the application during the deploy command.

          I have investigate the code and found that the issue is occured because the linkname about ejb doesn't change to "~" if it contains the symbols like ":".

          Show
          Jeremy_Lv added a comment - - edited Dear Hong: The related code in ApplicationLifecycle#deploy as follows: if (loadOnCurrentInstance(context)) { appInfo.setLibraries(commandParams.libraries()); try { notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.LOAD, context); appInfo.load(context, tracker); notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.LOAD, context); notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.START, context); appInfo.start(context, tracker); notifyLifecycleInterceptorsAfter(ExtendedDeploymentContext.Phase.START, context); } catch (Throwable loadException) { logger.log(Level.SEVERE, loadException.getMessage(), loadException); report.failure(logger, "Exception while loading the app" , null ); report.setFailureCause(loadException); tracker.actOn(logger); return null ; } } The code path can be excuted only if the value of "loadOnCurrentInstance(context)" in ApplicationLifecycle#deploy is true. For examples: 1.(1)if you excute the command like "asadmin deploy --enabled false --target inst1 --name test:v1 versioning-test.war", you will found the code path can't be excuted because of the value of "loadOnCurrentInstance(context)" is false. (2)then excute as "asadmin enable --target inst1 test:v1", the error message like "java.lang.RuntimeException: unable to create policy context directory" is thrown out. 2.However, if you excute the command like "asadmin deploy --target inst1 --name test:v1 versioning" with default value about enable the application, the application can be deployed but with some warning messages like "java.lang.RuntimeException: unable to create policy context directory" because the application has been loaded and then the code path has been excuted. Above all, the messages like "java.lang.RuntimeException: unable to create policy context directory" can be thrown out when you load the application during the deploy command. I have investigate the code and found that the issue is occured because the linkname about ejb doesn't change to "~" if it contains the symbols like ":".
          Hide
          Hong Zhang added a comment -

          When I was asking you to compare code paths earlier, I was referring to the asadmin deploy with enable attribute as true. So if you do a deploy to cluster with enable=true on a fresh server installation (with no other deploy or enable command executed before that), that code path does not work either? I thought we have sqe tests covering that. Can you double check this scenario?

          Show
          Hong Zhang added a comment - When I was asking you to compare code paths earlier, I was referring to the asadmin deploy with enable attribute as true. So if you do a deploy to cluster with enable=true on a fresh server installation (with no other deploy or enable command executed before that), that code path does not work either? I thought we have sqe tests covering that. Can you double check this scenario?
          Hide
          Jeremy_Lv added a comment - - edited

          So if you do a deploy to cluster with enable=true on a fresh server installation (with no other deploy or enable command executed before that), that code path does not work either? I thought we have sqe tests covering that. Can you double check this scenario?

          Yes,The code path can be excuted but doesn't work in this way. The web application contains ejb deployed successfully with some warning messages(java.lang.RuntimeException: unable to create policy context directory) thrown out.
          The context directory called "test~v1" can be created in the directory of GF_HOME\nodes\localhost-domain1\inst1\applications but can't be created in the directory of GF_HOME\nodes\localhost-domain1\inst1\generated\policy

          Show
          Jeremy_Lv added a comment - - edited So if you do a deploy to cluster with enable=true on a fresh server installation (with no other deploy or enable command executed before that), that code path does not work either? I thought we have sqe tests covering that. Can you double check this scenario? Yes,The code path can be excuted but doesn't work in this way. The web application contains ejb deployed successfully with some warning messages(java.lang.RuntimeException: unable to create policy context directory) thrown out. The context directory called "test~v1" can be created in the directory of GF_HOME\nodes\localhost-domain1\inst1\applications but can't be created in the directory of GF_HOME\nodes\localhost-domain1\inst1\generated\policy
          Hide
          Hong Zhang added a comment -

          I see. As the proposed fix is in security code, I will reassign the issue to security team so they can review your changes and also point you to the necessary security dev tests to run before checking in.

          Show
          Hong Zhang added a comment - I see. As the proposed fix is in security code, I will reassign the issue to security team so they can review your changes and also point you to the necessary security dev tests to run before checking in.
          Hide
          Jeremy_Lv added a comment -

          Dear JeffTancill, security team:
          Can you check my changes about this issue? if it looks good for you, can you tell me how to run the security dev tests and QL tests so that I can run them and check in my changes.
          Thanks a lot.

          Show
          Jeremy_Lv added a comment - Dear JeffTancill, security team: Can you check my changes about this issue? if it looks good for you, can you tell me how to run the security dev tests and QL tests so that I can run them and check in my changes. Thanks a lot.
          Hide
          Jeremy_Lv added a comment - - edited

          Here's the revised changes:

          Index: SecurityUtil.java
          ===================================================================
          --- SecurityUtil.java	(revision 55170)
          +++ SecurityUtil.java	(working copy)
          @@ -385,7 +385,7 @@
                       
                   } while (!unique);
           
          -        return app.getRegistrationName() + "/" + pseudonym;
          +        return VersioningUtils.getRepositoryName(app.getRegistrationName()) + "/" + pseudonym;
               }
           
               public static String getContextID(EjbBundleDescriptor ejbBundleDesc) {
          

          please check whether it is fine.

          Show
          Jeremy_Lv added a comment - - edited Here's the revised changes: Index: SecurityUtil.java =================================================================== --- SecurityUtil.java (revision 55170) +++ SecurityUtil.java (working copy) @@ -385,7 +385,7 @@ } while (!unique); - return app.getRegistrationName() + "/" + pseudonym; + return VersioningUtils.getRepositoryName(app.getRegistrationName()) + "/" + pseudonym; } public static String getContextID(EjbBundleDescriptor ejbBundleDesc) { please check whether it is fine.
          Hide
          Jeremy_Lv added a comment -

          Hi, Jeff:

          I have just ran the security dev tests without any changes and the test results are as follows:

          -----------------------
          PASSED=   736
          ------------  =========
          FAILED=   0
          ------------  =========
          DID NOT RUN=   4
          ------------  =========
          Total Expected=740
          ************************
          

          Is this the expected tests results? should all of the security tests passed?

          My work env. is Mac OS 10.8.3 and jdk is 1.7.0_21

          Thanks a lot!

          Show
          Jeremy_Lv added a comment - Hi, Jeff: I have just ran the security dev tests without any changes and the test results are as follows: ----------------------- PASSED= 736 ------------ ========= FAILED= 0 ------------ ========= DID NOT RUN= 4 ------------ ========= Total Expected=740 ************************ Is this the expected tests results? should all of the security tests passed? My work env. is Mac OS 10.8.3 and jdk is 1.7.0_21 Thanks a lot!
          Hide
          JeffTancill added a comment -

          Should pass all 740 but those 4 maybe something Mac specific, currently 740 pass on Linux. I'll have someone on the team with a Mac try a run but if your results after your changes match, I would say you are all set.

          Show
          JeffTancill added a comment - Should pass all 740 but those 4 maybe something Mac specific, currently 740 pass on Linux. I'll have someone on the team with a Mac try a run but if your results after your changes match, I would say you are all set.
          Hide
          Jeremy_Lv added a comment -

          I see. I will check the skip tests in my work environment too..
          Thanks a lot!

          Show
          Jeremy_Lv added a comment - I see. I will check the skip tests in my work environment too.. Thanks a lot!
          Hide
          Jeremy_Lv added a comment -

          The dev tests results after I have changed the source is the same as the original without any changes, I will checked in the changes later..

          Show
          Jeremy_Lv added a comment - The dev tests results after I have changed the source is the same as the original without any changes, I will checked in the changes later..
          Hide
          Jeremy_Lv added a comment -

          Changes has been checked in.
          Fix as the r62002.

          Show
          Jeremy_Lv added a comment - Changes has been checked in. Fix as the r62002.

            People

            • Assignee:
              JeffTancill
              Reporter:
              pdudits
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: