In combination with styles: "1.2025.3beta4" has "%newline()" bug (older version 1.2024.5 was working)

0 votes
asked Mar 30 in Bug by kirchsth (7,600 points)
edited Mar 30 by kirchsth

The original bug was found in C4-PlantUML (ENABLE_ALL_PLANT_ELEMENTS is not working anymore).
I could reduce it to a "style" problem with %newline() (I assume it is basically the same issue as it was with skinparam and %newline()) .

It can be reproduced with following sample (the skinparam part can be removed, it shows only the different behavior)

@startuml
!function $nl()
  ' workaround
  ' !return %breakline()
  !return %newline()
!endfunction

!function $elementTagSkinparams($element, $tagStereo, $fontColor)
  !$elementSkin = "skinparam " + $element + "<<" + $tagStereo + ">> {" + %newline()
  !if ($fontColor != "")
    !$elementSkin = $elementSkin + "    StereotypeFontColor " + $fontColor + %newline()
    !$elementSkin = $elementSkin + "    FontColor " + $fontColor + %newline()
  !endif
  !$elementSkin = $elementSkin + "}" + %newline()
  !return $elementSkin
!endfunction

' label colors cannot be set via skinparam use style
!function $labelElementTagSkinparams($tagStereo, $bgColor)
    !$tagSkin = $nl() + "<style>" + $nl()
    ' componentDiagram {
    !$tagSkin = $tagSkin + "  label {" + $nl()
    !$tagSkin = $tagSkin + "    ." + $tagStereo + " {" + $nl()
    !$tagSkin = $tagSkin + "      StereotypeFontColor " + $bgColor + $nl()
    !$tagSkin = $tagSkin + "      Fontcolor " + $bgColor + $nl()
    !$tagSkin = $tagSkin + "    }" + $nl()
    !$tagSkin = $tagSkin + "  }" + $nl()
    ' }
    !$tagSkin = $tagSkin + "</style>" + $nl()
  !return $tagSkin
!endfunction

!unquoted procedure $defineSkinparams($tagStereo, $bgColor, $fontColor)
  ' skinparam works based on updated server implementation
  !$tagSkin = $elementTagSkinparams("rectangle", $tagStereo, $fontColor)
  !$tagSkin = $tagSkin + $elementTagSkinparams("package", $tagStereo, $fontColor)

  ' style does not work, %newline() is not supported anymore
  !$tagSkin = $tagSkin + $labelElementTagSkinparams($tagStereo, $bgColor)
$tagSkin
!endprocedure

$defineSkinparams("red", white, red)
$defineSkinparams("blueboundary", white, blue)
$defineSkinparams("bluelabel", blue, white)

[C]

rectangle r <<red>> {
}

label "LABEL" as l <<bluelabel>>

package p <<blueboundary>> {
}
@enduml

If the workaround is activated and $nl() returns a %breakline() then it is working

!function $nl()
  ' with workaround is working
  !return %breakline()
!endfunction

with workaround it works with new (and old) server version

BR
Helmut

PS.: @Arnaud: I will try to fix the problem in C4-PlantUML too (that newline works independent of your fix) with a version specific helper function like $nl() that you can decide if you  want to add a style specific fix too - or not) 

commented Apr 6 by kirchsth (7,600 points)

Hi @Arnaud,

I tested it with multiple versions, and all produces basically the same stack.
(details see in https://github.com/plantuml-stdlib/C4-PlantUML/issues/389#issuecomment-2780712380, but I could be that I close the issue based on my C4-PlantUML changes).

My simplest found sample was following script:

@startuml

!unquoted procedure $defineSkinparams($tagStereo, $bgColor, $fontColor)
  !$elementSkin = "skinparam " + $element + "<<" + $tagStereo + ">> {" + %newline()
  !$elementSkin = $elementSkin + "}" + %newline()
' none of both is working
!$defs = $elementSkin + %newline()
'!$defs = $elementSkin + %breakline()
$defs
!endprocedure

$defineSkinparams("bluelabel", blue, white)

label "LABEL" as l <<bluelabel>>

@enduml

I can reproduce it with %newline() and %breakline(). For me it looks like that the problem is that 2 variables are combined (tested it with ex. .\plantuml-mit-1.2025.2.jar produces the same state exception; only changed lines in SourceFileReaderAbstract class)

Or you can see the illegal state exception on server too

https://www.plantuml.com/plantuml/uml/TP3DJeD058NtzoaE4unjv16GL8sxxle4WrpefCFSEZzXONnt6M99O-tkSFY-aypTXQXzJACbAfBxJ1AvmzdB1tV9CygEU-FuS3BkhBqUmwQCUZX4zYmLodPu4oj-JhsukEGj0KN9baTsCNjuXWeN7mfFkFoTewhhfLb7SzSq-ChjW-F96iUR_pQlFxFq_STuX1F7a1wjn2DCm2H-PWSgygF2xSIrV9TfFUlJBxKmLB3hreCHtLvCjJQnrIrRLI7d2jFHHDuIBItK_kNrVQ-W0opgUiMRXcWthwVH_W00

BR Helmut

commented Apr 7 by kirchsth (7,600 points)

sorry, I reduced it too much:

@startuml
!function $nl()
  ' with %breakline() it works
  ' !return %breakline()
  ' with %newline() it produces a crash with stacktrace
  !return %newline()
!endfunction

!unquoted procedure $defineSkinparams($tagStereo, $bgColor, $fontColor)
  !$element = "rectangle"
  !$elementSkin = "skinparam " + $element + "<<" + $tagStereo + ">> {" + %newline()
    !$elementSkin = $elementSkin + "    FontColor " + $fontColor + %newline()
  !$elementSkin = $elementSkin + "}" + %newline()

    !$tagSkin = $nl() + "<style>" + $nl()
    !$tagSkin = $tagSkin + "  label {" + $nl()
    !$tagSkin = $tagSkin + "    ." + $tagStereo + " {" + $nl()
    !$tagSkin = $tagSkin + "      StereotypeFontColor " + $bgColor + $nl()
    !$tagSkin = $tagSkin + "      Fontcolor " + $bgColor + $nl()
    !$tagSkin = $tagSkin + "    }" + $nl()
    !$tagSkin = $tagSkin + "  }" + $nl()
    !$tagSkin = $tagSkin + "</style>" + $nl()

  ' following line produces a crash with stack trace 
  !$mixed = $elementSkin + $tagSkin
  ' following line produces an error (without crash and stack trace)
  ' Error line 28 in file: .\TODO2.puml
  ' !$mixed = $tagSkin
$mixed
!endprocedure

$defineSkinparams("bluelabel", blue, red)

rectangle "RECTANGLE" as r <<bluelabel>>
label "LABEL" as l <<bluelabel>>

@enduml

Source in PlantUML Web Server

- The above source works with "plantuml-mit-1.2024.5.jar" but with "plantuml-mit-1.2025.2.jar" it produces a crash with stack trace. 
  ==> new version is not compatible with older versions

- If I use "%breakline()" in "$nl()"  then it works with new version too;

- If I uncomment "!$mixed = $tagSkin"  (and ignore $elementSkin) and the procedure writes only "$tagSkin" then an error message is written, and no crash anymore

BR Helmut

commented Apr 7 by plantuml (296,240 points)
Are you trying to make a version of C4-PlantUML that works with both "old" and "new" plantuml.jar ?
commented Apr 7 by kirchsth (7,600 points)

Yes, (I found the solution already, see my comment in your answer below)
The issue is more that the changed behaviour could produce problems in other diagrams too

!function $bl()
  !if (%function_exists("%breakline"))
    !return %breakline()
  !endif
  !return %newline()
!endfunction

commented Apr 7 by plantuml (296,240 points)

(Sorry, there are too many threads and I sometimes get lost :-)

The solution with %function_exists("%breakline") is a clever workaround.

I believe this should help you maintain a C4 library that's compatible with both the "old" and "new" versions of plantuml.jar.

That said, please let us know if you encounter issues in other diagrams using this strategy. We're happy to help.

Apologies again for all these changes, but they're for a better PlantUML!

1 Answer

0 votes
answered Apr 6 by plantuml (296,240 points)

BTW, you do have to use %breakline() and not %newline():

So the correct syntax is:

https://editor.plantuml.com/uml/fLDTJy8m57rVmdyuMsPWST4_C0cA-CIRlXaVkks22rqxkpQ64FwxRISJWsZ0lVIklUUZTsUJLZEbJSq7mI085qOKkf82CMSvyHcdceH-Oil7LIKQfbZTZc9jNpKfaYdYV3cLNAfa4C0-eJ-phRZ1HQw8hNWbQ9JW4b7MwZMdSMJh_QCEE4GXwqOAAtPViQNLmUQGiYyj7U0TOlCpuN4OSEKWNxVmssVG01rUhnjwa4BxGS1pVqxb34f7LFoVQ7lgTOu0XjZ-ZiokZt_MK94sIlJzDbyaobt4VDwCU3DIKub6oO9AemXnIGjByKVWRBNOpRmJspTuSdY_M-pDE8-7VgAS6_8IKGfNftX_hJGbhlrv-kAMBfpH_FPkDe_0Md1aMOyRZrtFn4hP7-y3

@startuml

!function $labelElementTagSkinparams($tagStereo, $bgColor)
    !$tagSkin = %breakline() + "<style>" + %breakline()
    ' componentDiagram {
    !$tagSkin = $tagSkin + "  label {" + %breakline()
    !$tagSkin = $tagSkin + "    ." + $tagStereo + " {" + %breakline()
    !$tagSkin = $tagSkin + "      StereotypeFontColor " + $bgColor + %breakline()
    !$tagSkin = $tagSkin + "      Fontcolor " + $bgColor + %breakline()
    !$tagSkin = $tagSkin + "    }" + %breakline()
    !$tagSkin = $tagSkin + "  }" + %breakline()
    ' }
    !$tagSkin = $tagSkin + "</style>" + %breakline()
  !return $tagSkin
!endfunction

!unquoted procedure $defineSkinparams($tagStereo, $bgColor, $fontColor)
  !$tagSkin = $labelElementTagSkinparams($tagStereo, $bgColor)
$tagSkin
!endprocedure

$defineSkinparams("bluelabel", blue, white)

[C]

label "LABEL" as l <<bluelabel>>

@enduml

commented Apr 7 by kirchsth (7,600 points)

related to %breakline() - %newline(), I know. I use following implementation in C4-Plantuml that I'm compatible with older versions too

!function $bl()
  !if (%function_exists("%breakline"))
    !return %breakline()
  !endif
  !return %newline()
!endfunction

...