Skip to content

CAMEL-22409: zwsp invisible character breaks property at runtime#22281

Open
claudio4j wants to merge 1 commit intoapache:mainfrom
claudio4j:remove_zwsp
Open

CAMEL-22409: zwsp invisible character breaks property at runtime#22281
claudio4j wants to merge 1 commit intoapache:mainfrom
claudio4j:remove_zwsp

Conversation

@claudio4j
Copy link
Contributor

@claudio4j claudio4j commented Mar 26, 2026

Description

There is an incoming PR to camel-website css that's going to break words when there is a long property name.

Target

  • I checked that the commit is targeting the correct branch (Camel 4 uses the main branch)

Tracking

  • If this is a large change, bug fix, or code improvement, I checked there is a JIRA issue filed for the change (usually before you start working on it).

Apache Camel coding standards and style

  • I checked that each commit in the pull request has a meaningful subject line and body.
  • I have run mvn clean install -DskipTests locally from root folder and I have committed all auto-generated changes.

@github-actions
Copy link
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using build-all, build-dependents, skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

Copy link
Contributor

@gnodet gnodet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good fix for a real user-facing bug — the {zwsp} (Zero-Width Space) character silently breaking copy-pasted property names is nasty to debug.

One observation (non-blocking): with "" as separator, getShortName(int) is now effectively a no-op. Here's why:

  1. wrapCamelCaseWords splits camelCase into space-separated words via replaceAll("(?=[A-Z][a-z])", " "), e.g. "camel.main.auto Configuration Enabled"
  2. wrapWords reassembles them, inserting lineSep at word boundaries past the watermark
  3. With lineSep="", those insertions are empty — the words just concatenate back to the original string
  4. wrapCamelCaseWords uppercases the first char, then getShortName lowercases it back — cancelling out

So the method does real work (regex, word wrapping, case conversion) but it's all a round-trip back to the original name. Could be simplified to return name; in a follow-up if desired.

Claude Code on behalf of Guillaume Nodet

Comment on lines 347 to 349
String text = Strings.wrapCamelCaseWords(name, watermark, "");
// ensure the option name starts with lower-case
return Character.toLowerCase(text.charAt(0)) + text.substring(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With "" as separator, wrapCamelCaseWords splits camelCase into words and joins them back unchanged, and the uppercase/lowercase operations cancel each other out — making this method a no-op.

Suggested change
String text = Strings.wrapCamelCaseWords(name, watermark, "");
// ensure the option name starts with lower-case
return Character.toLowerCase(text.charAt(0)) + text.substring(1);
return name;

The method itself (and the watermark parameter) could be removed entirely in a follow-up PR, replacing row.getShortName(30) with row.name in the two MVEL templates (main-options.mvel and jbang-options.mvel).

Claude Code on behalf of Guillaume Nodet

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify where is the uppercase happening and why it is cancelling it out?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrapCamelCaseWords in Strings.java:55 uppercases the first character:

text = Character.toUpperCase(text.charAt(0)) + text.substring(1);

Then getShortName in BaseOptionModel.java:349 lowercases it right back:

return Character.toLowerCase(text.charAt(0)) + text.substring(1);

Since property names already start with lowercase (e.g. camel.main.autoConfigurationEnabled), it's cCc — a round-trip back to the original.

Claude Code on behalf of Guillaume Nodet

Copy link
Contributor

@apupier apupier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand all the side-effect that this could have.

These {zwsp} were introduced to fix this problem https://issues.apache.org/jira/browse/CAMEL-13923 is it still working fine?

also I notice that previously it was Strings.wrapCamelCaseWords(name, watermark, " "); and not Strings.wrapCamelCaseWords(name, watermark, "");
This is why the change is putting the whole name in a single camel case name and not with a space in it, right?

This invisible character was used to split the word in tables, right? If I understand well, we will need to have apache/camel-website#1549 to have it split correctly? I was unable to navigate to the page showing thsi kind of content with the netlify link (```This file exists solely to defeat the limitations of the link checker, that is unaware of the .htaccess redirect from this page to the latest released version.

If you see this, you are not viewing the site through httpd or there is something wrong with the .htaccess file: in the latter case please let the camel developers know.

Do you have some screenshots from local usage? or a direct link to the correct place to look at please?

@claudio4j
Copy link
Contributor Author

Having the mvel templates to use the row.name to set the full property name and the css in camel-website takes care to word wrap the long property names in the rendered html.
As the getShortName(int) is only used to add the zwsp char from the mvel templates, after this change, not in use anymore, so it's deprecated.

@claudio4j
Copy link
Contributor Author

These {zwsp} were introduced to fix this problem https://issues.apache.org/jira/browse/CAMEL-13923 is it still working fine?

the actual issue with the zwsp is better described in CAMEL-22409 about copy/paste.

If I understand well, we will need to have apache/camel-website#1549 to have it split correctly?

yes, the css will word wrap the long property names.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants