Skip to content

8490: Include numeric types without Persister in "Add Filter from Attribute" menu#699

Open
youngledo wants to merge 17 commits intoopenjdk:masterfrom
youngledo:event-browser-menu
Open

8490: Include numeric types without Persister in "Add Filter from Attribute" menu#699
youngledo wants to merge 17 commits intoopenjdk:masterfrom
youngledo:event-browser-menu

Conversation

@youngledo
Copy link
Contributor

@youngledo youngledo commented Jan 9, 2026

Problem

Attributes with numeric ContentTypes that don't have a Persister (such as primitive types: byte, short, int, long, float, double, char) are
excluded from the "Add Filter from Attribute" context menu in the Event Browser's filter editor.

Steps to reproduce:

  1. Open a JFR file containing events with primitive numeric fields (e.g., Spring Framework's FlightRecorderStartupEvent with long eventId and
    long parentId)
  2. In Event Browser, right-click on a column → Select "Show Filter"
  3. Right-click on the filter area → Select "Add Filter from Attribute"
  4. Expected: All filterable attributes should appear in the menu
  5. Actual: Primitive numeric type attributes are missing from the menu
image

Root Cause

The getPersistableAttributes() method in DataPageToolkit.java (line 1006-1007) filters attributes based on whether their ContentType has a
Persister:

.filter(a -> a.equals(JfrAttributes.EVENT_TYPE) || (a.getContentType() instanceof RangeContentType)
    || (a.getContentType().getPersister() != null))

However, primitive numeric types use these ContentTypes which don't have a Persister:

  • UnitLookup.RAW_NUMBER - used by all primitive numeric types (byte, short, int, long, float, double, char)
  • UnitLookup.RAW_LONG - used by some custom Long attributes
  • UnitLookup.COUNT, UnitLookup.INDEX, UnitLookup.IDENTIFIER - legacy numeric types

These types return null from getPersister() (see ContentType.java:99-101), causing them to be filtered out.

Why this is incorrect:

Even though these types cannot be persisted to strings, they fully support filtering via ItemFilters.equals(). Excluding them from the filter
menu is inconsistent with their actual capabilities.

Solution

Add a helper method isFilterableNumericType() to identify numeric ContentTypes that support filtering even without a Persister, and include them
in the filter:

private static boolean isFilterableNumericType(IAttribute<?> attribute) {
      org.openjdk.jmc.common.unit.ContentType<?> ct = attribute.getContentType();
      return ct.equals(UnitLookup.RAW_NUMBER) || ct.equals(UnitLookup.RAW_LONG)|| ct.equals(UnitLookup.COUNT) || ct.equals(UnitLookup.INDEX)
              || ct.equals(UnitLookup.IDENTIFIER);
  }

Update the filter condition to include these types:

  .filter(a -> a.equals(JfrAttributes.EVENT_TYPE)
      || (a.getContentType() instanceof RangeContentType)
      || (a.getContentType().getPersister() != null)
      || isFilterableNumericType(a))

Testing

Tested with Spring Framework's FlightRecorderStartupEvent which has primitive long fields:

  • Before fix: eventId and parentId attributes were missing from "Add Filter from Attribute" menu
  • After fix: All primitive numeric attributes appear correctly in the menu and filters work as expected
453be33a-e65c-4fe2-9a84-a060afa99671

Attachment: app.jfr.zip

Related issues: spring-projects/spring-framework#36077 (comment)


Progress

  • Commit message must refer to an issue
  • Change must be properly reviewed (1 review required, with at least 1 Committer)

Issue

  • JMC-8490: Include numeric types without Persister in "Add Filter from Attribute" menu (Bug - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jmc.git pull/699/head:pull/699
$ git checkout pull/699

Update a local copy of the PR:
$ git checkout pull/699
$ git pull https://git.openjdk.org/jmc.git pull/699/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 699

View PR using the GUI difftool:
$ git pr show -t 699

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jmc/pull/699.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Jan 9, 2026

👋 Welcome back youngledo! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Jan 9, 2026

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@youngledo
Copy link
Contributor Author

youngledo commented Jan 9, 2026

I don't have access to JBS yet. Could someone please create an issue for this PR?

@aymane-harmaz Hello, Can you help me?
May I ask, what are the ways I can apply for this account?

@aymane-harmaz
Copy link
Member

@youngledo Thanks for opening this PR.

I have opened a JBS ticket for you here : https://bugs.openjdk.org/browse/JMC-8490

In order to obtain write access to JBS you need to have the Author role, You can find more information about the process and requirements here : https://openjdk.org/guide/#becoming-an-author

@youngledo youngledo changed the title Fix: Include numeric types without Persister in "Add Filter from Attribute" menu. 8490: Include numeric types without Persister in "Add Filter from Attribute" menu. Jan 12, 2026
@youngledo youngledo changed the title 8490: Include numeric types without Persister in "Add Filter from Attribute" menu. 8490: Include numeric types without Persister in "Add Filter from Attribute" menu Jan 12, 2026
@openjdk openjdk bot added the rfr label Jan 12, 2026
@mlbridge
Copy link

mlbridge bot commented Jan 12, 2026

@thegreystone
Copy link
Member

The current PR will allow these attributes to appear in the menu, but users will likely hit errors when trying to use or save filters on them. I'd suggest either:

  1. (Preferred) Add proper LeafContentType persisters to the numeric types in UnitLookup
  2. (Minimal) Add null-safety handling in the filter persistence code alongside this change

Happy to discuss further or help with implementation!

@youngledo
Copy link
Contributor Author

Welcome to vote. If there are no votes, I will implement according to the first suggestion.

This commit adds IPersister implementation to the following numeric types:
- RAW_NUMBER
- RAW_LONG
- COUNT
- INDEX
- IDENTIFIER

These types previously had no Persister, which would cause errors when users
tried to edit or save filters on them. By implementing the IPersister interface
via LeafContentType, these types can now be properly persisted and restored.

Changes:
- Modified createRawNumber() to return a LeafContentType with full persister support
- Modified createRawLong() to return a LeafContentType with full persister support
- Modified createCount() to return a LeafContentType with full persister support
- Modified createIdentifier() to return a LeafContentType with full persister support
- Modified createIndex() to return a LeafContentType with full persister support
- Added parseNumber() helper method to parse string representations of numbers

The persister implementation supports:
- persistableString(): converts Number values to strings for storage
- parsePersisted(): parses strings back to Number objects
- interactiveFormat(): user-friendly string representation
- parseInteractive(): parses user input strings

This fix resolves the issue where attributes with these numeric content types
would appear in the "Add Filter from Attribute" menu but fail when users
attempted to use or save filters on them.
This commit adds validation for empty and blank strings in the parseNumber()
method and RAW_LONG persister methods to prevent NumberFormatException
when users clear input fields in the filter editor.

Changes:
- parseNumber(): Check for null/empty string before parsing
- createRawLong() parsePersisted(): Check for empty string before parsing
- createRawLong() parseInteractive(): Check for empty string before parsing
- Updated javadoc to document the NumberFormatException for empty strings

This fixes the issue where editing a numeric filter value and clearing
the input field would cause an unhandled NumberFormatException with
the message "empty String" instead of a more user-friendly error.
Changed parseNumber() to always return Long (for integers) or Double (for decimals)
instead of Integer/Long/Double hierarchy to ensure type compatibility when
comparing filter values.

Problem:
- Previously parseNumber("100") returned Integer(100)
- If actual data was Long(100L), comparison would fail because
  Integer(100).equals(Long(100L)) returns false
- This caused filters to not match any data even when values existed

Solution:
- parseNumber() now returns Long for all integer values
- Returns Double only for decimal values
- This ensures Long.equals(Long) comparisons work correctly
- All RAW_NUMBER, COUNT, INDEX, IDENTIFIER types now use consistent types
Modified both UnitLookup and CommonCellEditors to properly handle empty or invalid
input when editing numeric type filters, preventing "Unhandled event loop exception" errors.

Changes:
1. UnitLookup.java:
   - Added try-catch blocks to parsePersisted() and parseInteractive() methods
   - Catch NumberFormatException and throw IllegalArgumentException with clear message
   - Applied to RAW_NUMBER, RAW_LONG, COUNT, INDEX, and IDENTIFIER types

2. CommonCellEditors.java:
   - Added catch block for IllegalArgumentException and NumberFormatException
   - Displays error message in UI when user enters invalid value
   - Prevents unhandled exception from crashing the UI

This ensures a user-friendly experience when editing numeric filters, especially
when clearing input fields.
@openjdk
Copy link

openjdk bot commented Jan 31, 2026

@youngledo Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration. See OpenJDK Developers’ Guide for more information.

youngledo and others added 7 commits January 31, 2026 22:36
Reviewed-by: aptmac, clanger
Reviewed-by: aptmac
This file should not be tracked as it contains local settings.
Added .claude/ to .gitignore to prevent future commits.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@thegreystone
Copy link
Member

Will the removal of the .classpath files cause any trouble running JMC from within the Eclipse development environment? I am not perfectly sure, but I have a faint memory of a few of them being slightly specialized.

This commit restores the .classpath files that were previously removed.
These files are essential for JMC development in Eclipse IDE due to the
project's hybrid nature as both a Maven and PDE/OSGi application.
@youngledo
Copy link
Contributor Author

Will the removal of the .classpath files cause any trouble running JMC from within the Eclipse development environment? I am not perfectly sure, but I have a faint memory of a few of them being slightly specialized.

Thank you for the reminder, I have recovered.

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

Labels

Development

Successfully merging this pull request may close these issues.

4 participants