Project

General

Profile

Bug #10469

incremental conversion when basepath is more than one folder (aka abl/foo) with #5586

Added by Constantin Asofiei 11 months ago. Updated 9 months ago.

Status:
Test
Priority:
Urgent
Target version:
-
Start date:
Due date:
% Done:

100%

billable:
No
vendor_id:
GCD
case_num:
version_reported:
version_resolved:
trunk/16220
production:
No
env_name:
topics:

Related issues

Related to Conversion Tools - Feature #5586: move all conversion artifacts/outputs into the cvtdb or into a dedicated directory sub-tree that is separate from the original 4GL code/schema inputs Closed

History

#1 Updated by Constantin Asofiei 11 months ago

  • Related to Feature #5586: move all conversion artifacts/outputs into the cvtdb or into a dedicated directory sub-tree that is separate from the original 4GL code/schema inputs added

#2 Updated by Constantin Asofiei 11 months ago

  • Priority changed from Normal to Urgent
There is a bug when basepath="./abl/hotel/" and cvtpath="./cvt". Incremental conversion will fail because Configuration.getPathToSourceFileFromConversionFolder is broken - it replaces i.e. ./cvt/hotel/oo/Foo.cls.ast with ./abl/hotel/hotel/oo/Foo.cls:
      if (filename.startsWith(cvtpath))
      {
         filename = filename.replace(cvtpath, basepath);
      }

where:
  • filename="./cvt/hotel/oo/Foo.cls.ast"
  • cvtpath="./cvt"
  • basepath="./abl/hotel"

This results in incremental conversion not cleaning up properly the cvtdb database when adding files to conversion, as the result of this will be ./abl/hotel/hotel/oo/Foo.cls

The .ast file exists as ./cvt/hotel/oo/Foo.cls.ast on disk.

#3 Updated by Dănuț Filimon 11 months ago

  • Status changed from New to WIP

I'll look into the issue right away.

#4 Updated by Dănuț Filimon 11 months ago

Constantin, is there any configuration missing? I get this error with the mentioned configuration:

[java] ---------------------------
     [java] throwException(err)
     [java] ^  { Invalid basepath! basepath = ./abl/hotel; pkg = ./abl; [BLOCK id <12884901889> 0:0] }
     [java] ---------------------------
     [java] EXPRESSION EXECUTION ERROR:
     [java] ---------------------------
     [java] relpkg = execLib("rel_pkg_path")
     [java]          ^  { Expression execution error @1:1 }
     [java] ---------------------------
     [java] ERROR:
     [java] com.goldencode.p2j.pattern.TreeWalkException: ERROR!  Active Rule:
     [java] -----------------------
     [java]       RULE REPORT      
     [java] -----------------------
     [java] Rule Type :   WALK
     [java] Source AST:  [ block ] BLOCK/ @0:0 {12884901889}
     [java] Copy AST  :  [ block ] BLOCK/ @0:0 {12884901889}
     [java] Condition :  throwException(err)
     [java] Loop      :  false
     [java] --- END RULE REPORT ---
     [java] 
     [java] 
     [java] 
     [java]     at com.goldencode.p2j.pattern.PatternEngine.run(PatternEngine.java:1102)
     [java]     at com.goldencode.p2j.convert.TransformDriver.processTrees(TransformDriver.java:610)
     [java]     at com.goldencode.p2j.convert.ConversionDriver.back(ConversionDriver.java:574)
     [java]     at com.goldencode.p2j.convert.TransformDriver.executeJob(TransformDriver.java:1058)
     [java]     at com.goldencode.p2j.convert.ConversionDriver.main(ConversionDriver.java:1235)
     [java] Caused by: com.goldencode.expr.ExpressionException: Expression execution error @1:10
     [java]     at com.goldencode.expr.Expression.execute(Expression.java:495)
     [java]     at com.goldencode.p2j.pattern.Rule.apply(Rule.java:500)
     [java]     at com.goldencode.p2j.pattern.RuleContainer.apply(RuleContainer.java:597)
     [java]     at com.goldencode.p2j.pattern.RuleSet.apply(RuleSet.java:98)
     [java]     at com.goldencode.p2j.pattern.PatternEngine.apply(PatternEngine.java:1675)
     [java]     at com.goldencode.p2j.pattern.PatternEngine.processAst(PatternEngine.java:1582)
     [java]     at com.goldencode.p2j.pattern.PatternEngine.processAst(PatternEngine.java:1515)
     [java]     at com.goldencode.p2j.pattern.PatternEngine.run(PatternEngine.java:1065)
     [java]     ... 4 more
     [java] Caused by: com.goldencode.expr.ExpressionException: Expression execution error @1:1
     [java]     at com.goldencode.expr.Expression.execute(Expression.java:495)
     [java]     at com.goldencode.p2j.pattern.Rule.apply(Rule.java:500)
     [java]     at com.goldencode.p2j.pattern.Rule.executeActions(Rule.java:751)
     [java]     at com.goldencode.p2j.pattern.Rule.coreProcessing(Rule.java:717)
     [java]     at com.goldencode.p2j.pattern.Rule.apply(Rule.java:537)
     [java]     at com.goldencode.p2j.pattern.Rule.executeActions(Rule.java:751)
     [java]     at com.goldencode.p2j.pattern.Rule.coreProcessing(Rule.java:717)
     [java]     at com.goldencode.p2j.pattern.Rule.apply(Rule.java:537)
     [java]     at com.goldencode.p2j.pattern.NamedFunction.execute(NamedFunction.java:458)
     [java]     at com.goldencode.p2j.pattern.AstSymbolResolver.execute(AstSymbolResolver.java:803)
     [java]     at com.goldencode.p2j.pattern.CommonAstSupport$Library.execLib(CommonAstSupport.java:1908)
     [java]     at com.goldencode.expr.CE6550.execute(Unknown Source)
     [java]     at com.goldencode.expr.Expression.execute(Expression.java:398)
     [java]     ... 11 more
     [java] Caused by: com.goldencode.p2j.pattern.UserGeneratedException: Invalid basepath! basepath = ./abl/hotel; pkg = ./abl; [BLOCK id <12884901889> 0:0]
     [java]     at com.goldencode.p2j.pattern.CommonAstSupport$Library.throwException(CommonAstSupport.java:3742)
     [java]     at com.goldencode.p2j.pattern.CommonAstSupport$Library.throwException(CommonAstSupport.java:3727)
     [java]     at com.goldencode.expr.CE6644.execute(Unknown Source)
     [java]     at com.goldencode.expr.Expression.execute(Expression.java:398)
     [java]     ... 23 more
     [java] 

#5 Updated by Constantin Asofiei 11 months ago

You need to add :${P2J_HOME}/abl/hotel/ to propath in p2j.cfg.xml. If we look in Configuration.getPathToConversionFolder:

      String base = normalizeFilename(getParameter("basepath")) + File.separator;
      // we have to get the first directory from base, for example:
      // we have getParameter(basepath)="abl/src", we have to move the artifacts to "cvt/src" 
      String basepath = "." + File.separator;
      if (!base.equals(basepath))
      {
         // we make sure we have something after "./" to use split
         basepath = basepath + base.split(Pattern.quote(File.separator))[1] + File.separator;
      }

where basepath becomes from ./abl/hotel/ to ./abl.

This ensures that the .ast and such files have the same paths as where their source resides, but the reverse is not be computed right in getPathToSourceFileFromConversionFolder. If I change it to this:

   public static String getPathToSourceFileFromConversionFolder(String filename, String ext, boolean relative)
   {
      if (!relative)
      {
         filename = normalizeFilename(filename);
      }
      String cvtpath = DEFAULT_CVT;
      try
      {
         cvtpath = normalizeFilename(getConversionFolder()) + File.separator;
      }
      catch (ConfigurationException e)
      {
         LOG.log(Level.SEVERE, e.getMessage(), e);
      }

      String base = normalizeFilename(getParameter("basepath")) + File.separator;
      // we have to get the first directory from base, for example:
      // we have getParameter(basepath)="abl/src", we have to move the artifacts to "cvt/src" 
      String basepath = "." + File.separator;
      if (!base.equals(basepath))
      {
         // we make sure we have something after "./" to use split
         basepath = basepath + base.split(Pattern.quote(File.separator))[1] + File.separator;
      }

      if (filename.startsWith(cvtpath))
      {
         filename = filename.replace(cvtpath, basepath);
      }
      if (filename.endsWith(ext))
      {
         filename = filename.substring(0, filename.length() - ext.length());
      }

      return filename;
   }

Looks like it works - the 'basepath' which gets replaced is computed in the same way as in getPathToConversionFolder.

#6 Updated by Dănuț Filimon 11 months ago

I already tried to add abl/hotel to the propath:

<parameter name="propath"          value="${P2J_HOME}:${P2J_HOME}/abl/:${P2J_HOME}/abl/common:${P2J_HOME}/abl/hotel/" />
and the error is the same.

The fix from #10469-5 makes sense.

#7 Updated by Dănuț Filimon 11 months ago

I experimented with the cvt and basepath parameters and also tried the scenario where:
  • basepath is ./abl/hotel
  • cvt is ./cvt/tmp

For the code

      String base = normalizeFilename(getParameter("basepath")) + File.separator;
      String basepath = "." + File.separator;

      if (!base.equals(basepath))
      {
         basepath = basepath + base.split(Pattern.quote(File.separator))[1] + File.separator;
      }
, the base will be ./abl/hotel/, the basepath will be ./abl and the filename will end up ./abl/hotel/oo/Foo.cls which is correct. The only problem I see with this code is that it's hard to read and understand.

The patch looks like this:

=== modified file 'src/com/goldencode/p2j/cfg/Configuration.java'
--- old/src/com/goldencode/p2j/cfg/Configuration.java    2025-07-02 10:14:42 +0000
+++ new/src/com/goldencode/p2j/cfg/Configuration.java    2025-08-26 07:09:02 +0000
@@ -766,7 +766,6 @@
       {
          filename = normalizeFilename(filename);
       }
-      String basepath = Configuration.getParameter("basepath") + File.separator;
       String cvtpath = DEFAULT_CVT;
       try
       {
@@ -776,6 +775,20 @@
       {
          LOG.log(Level.SEVERE, e.getMessage(), e);
       }
+      
+      String base = normalizeFilename(getParameter("basepath")) + File.separator;
+      String basepath = "." + File.separator;
+      
+      if (!base.equals(basepath))
+      {
+         String[] parts = base.split(Pattern.quote(File.separator));
+         if (parts.length > 1)
+         {
+            // parts[0] will be ".", while parts[1] is the first directory of base
+            basepath += parts[1] + File.separator;
+         }
+      }
+      
       if (filename.startsWith(cvtpath))
       {
          filename = filename.replace(cvtpath, basepath);

Constantin, this is not much different from the original code, but it's a bit more safe because we check if we have the base directory. What do you think?

#8 Updated by Dănuț Filimon 11 months ago

  • % Done changed from 0 to 100
  • Status changed from WIP to Review
  • reviewer Constantin Asofiei added

Committed the patch from #10469-7 to 10469a/16135. Constantin, please review.

#9 Updated by Constantin Asofiei 11 months ago

I noticed something else during incremental conversion: the file is reported using ./cvt/ instead of ./abl. Can you check this also, Danut?

#10 Updated by Dănuț Filimon 11 months ago

Constantin Asofiei wrote:

I noticed something else during incremental conversion: the file is reported using ./cvt/ instead of ./abl. Can you check this also, Danut?

The file should be reported using ./cvt when it's an artifact (.jast, .cache, .ast) and using ./abl/ only for the original source file (.p, .w, .cls). What is the conversion step where you see this issue?

#11 Updated by Constantin Asofiei 11 months ago

Dănuț Filimon wrote:

Constantin Asofiei wrote:

I noticed something else during incremental conversion: the file is reported using ./cvt/ instead of ./abl. Can you check this also, Danut?

The file should be reported using ./cvt when it's an artifact (.jast, .cache, .ast) and using ./abl/ only for the original source file (.p, .w, .cls). What is the conversion step where you see this issue?

Incremental conversion of a .cls file and a dependency not being included in the incremental conversion - you change Foo.cls which depends on Bar.cls and only run incremental for Foo.cls.

#12 Updated by Dănuț Filimon 11 months ago

The only ./cvt/ usage is in this phase:

     [java] ------------------------------------------------------------------------------
     [java] Generate Java Source Business Logic and Frames Classes
     [java] ------------------------------------------------------------------------------
     [java] 
     [java] ./cvt/hotel/oo/Foo.cls.jast
     [java] Elapsed job time:  00:00:00.148
which is correct.

#13 Updated by Dănuț Filimon 10 months ago

Constantin, I found a similar issue and mentioned it in #10536-9. Let me know if it is the same, as I've been testing a fix using ETF incremental.

#15 Updated by Dănuț Filimon 10 months ago

  • Status changed from Review to Pending

The fix from 10469a was integrated in 6083a.

#16 Updated by Greg Shah 10 months ago

Code Review Task Branch 6083a Revision 16159

The changes make sense.

#17 Updated by Constantin Asofiei 10 months ago

Danut, I need to apply this fix to 9457c - what exactly should I patch? What was in 10469a or something else?

#18 Updated by Dănuț Filimon 10 months ago

Constantin Asofiei wrote:

Danut, I need to apply this fix to 9457c - what exactly should I patch? What was in 10469a or something else?

At this moment, you can patch what was in 10469a. 6083a rewrites this change due to DRY.

#19 Updated by Dănuț Filimon 10 months ago

Dănuț Filimon wrote:

Constantin Asofiei wrote:

Danut, I need to apply this fix to 9457c - what exactly should I patch? What was in 10469a or something else?

At this moment, you can patch what was in 10469a. 6083a rewrites this change due to DRY.

This is the patch from 6083a to fix the issue mentioned in #10469-10:

=== modified file 'src/com/goldencode/p2j/convert/db/ConversionData.java'
--- old/src/com/goldencode/p2j/convert/db/ConversionData.java    2025-09-05 08:23:22 +0000
+++ new/src/com/goldencode/p2j/convert/db/ConversionData.java    2025-09-11 09:56:11 +0000
@@ -28,6 +28,7 @@
 **     DDF 20250903 Fix md5 being initialized to null instead of filename.
 **     DDF 20250904 Added utility methods to support deleted conversion files.
 **     DDF 20250905 Only save the registry once in cleanupDeletedFiles().
+**     DDF 20250911 Fix scenario where a nonexistent conversion artifact ends up as a dependency.
 */

 /*
@@ -142,6 +143,11 @@

       for (int i = 0; i < exts.length; i++)
       {
+         if (exts[i].isEmpty())
+         {
+            continue;
+         }
+         
          long astId = mgr.getTreeId(Configuration.getPathToConversionFolder(file, exts[i]));
          if (astId != AstManager.INVALID_ID)
          {
@@ -239,7 +245,7 @@
          {
             if (!ext.isEmpty() && name.endsWith(ext))
             {
-               name = name.substring(0, name.length() - ext.length());
+               name = Configuration.getPathToSourceFileFromConversionFolder(name, ext);
                break;
             }
          }

There are more changes aside from this one in the branch, so I extracted this bit.

#20 Updated by Dănuț Filimon 9 months ago

  • Status changed from Pending to Test
  • version_resolved set to trunk/16220

Branch 6083a was merged to trunk revision 16220 and archived.

#21 Updated by Constantin Asofiei 9 months ago

Danut, is 10469a still required? I see it was archived as dead.

#22 Updated by Dănuț Filimon 9 months ago

Constantin Asofiei wrote:

Danut, is 10469a still required? I see it was archived as dead.

The fix from 10469a was integrated in 6083a and reached trunk when the branch was merged.

Also available in: Atom PDF