Skip to content

[java] fix loading "isDisplayed.js" and other resources in OSGI environment#17257

Merged
asolntsev merged 1 commit intoSeleniumHQ:trunkfrom
asolntsev:fix/17251-resources-in-osgi-environment
Mar 29, 2026
Merged

[java] fix loading "isDisplayed.js" and other resources in OSGI environment#17257
asolntsev merged 1 commit intoSeleniumHQ:trunkfrom
asolntsev:fix/17251-resources-in-osgi-environment

Conversation

@asolntsev
Copy link
Copy Markdown
Contributor

In OSGi, each bundle has its own classloader that can only see its own resources.

🔗 Related Issues

Fixes #17251

🔧 Implementation Notes

Read.class.getResource(...) uses the classloader of the bundle containing class Read. It would not find resource "isDisplayed.js" since it's located in another bundle. The right solution is to use a class from the bundle that owns the resource.

🔄 Types of changes

  • Bug fix (backwards compatible)

@selenium-ci selenium-ci added C-java Java Bindings B-devtools Includes everything BiDi or Chrome DevTools related labels Mar 25, 2026
@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Fix resource loading in OSGi environment by using resource owner class

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Fix resource loading in OSGi environment by using resource owner class
• Deprecate single-argument resourceAsString() method
• Add new overloaded resourceAsString(Class, String) method
• Update all callers to pass resource owner class parameter

Grey Divider

File Changes

1. java/src/org/openqa/selenium/io/Read.java 🐞 Bug fix +11/-1

Add resource owner class parameter to resourceAsString

• Deprecated single-argument resourceAsString(String) method with javadoc warning
• Added new overloaded resourceAsString(Class<?>, String) method that accepts resource owner class
• Updated deprecated method to delegate to new method using Read.class

java/src/org/openqa/selenium/io/Read.java


2. java/src/org/openqa/selenium/devtools/events/CdpEventTypes.java 🐞 Bug fix +3/-1

Pass resource owner class to resourceAsString

• Updated domMutation() method to pass CdpEventTypes.class to resourceAsString()
• Ensures resource is loaded from correct bundle in OSGi environment

java/src/org/openqa/selenium/devtools/events/CdpEventTypes.java


3. java/src/org/openqa/selenium/remote/RemoteScript.java 🐞 Bug fix +2/-1

Pass resource owner class to resourceAsString

• Updated addDomMutationHandler() method to pass getClass() to resourceAsString()
• Ensures bidi-mutation-listener.js is loaded from correct bundle

java/src/org/openqa/selenium/remote/RemoteScript.java


View more (2)
4. java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpCommandCodec.java 🐞 Bug fix +1/-1

Pass resource owner class to resourceAsString

• Updated executeAtom() method to pass getClass() to resourceAsString()
• Ensures atom scripts are loaded from correct bundle in OSGi environment

java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpCommandCodec.java


5. java/test/org/openqa/selenium/io/ReadTest.java 🧪 Tests +1/-1

Update test to use new resourceAsString signature

• Updated test to pass Read.class parameter to resourceAsString() method
• Aligns test with new method signature

java/test/org/openqa/selenium/io/ReadTest.java


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review bot commented Mar 25, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📎 Requirement gaps (0) 📐 Spec deviations (0)

Grey Divider


Action required

1. resourceAsString missing null checks 📘 Rule violation ✓ Correctness
Description
The new overload resourceAsString(Class<?>, String) dereferences resourceOwner and passes
resource to getResourceAsStream without validating required inputs, which can cause an unclear
NullPointerException at runtime. This violates the fail-fast requirement for required inputs with
actionable errors.
Code

java/src/org/openqa/selenium/io/Read.java[R66-68]

+  public static String resourceAsString(Class<?> resourceOwner, String resource) {
+    try (InputStream stream = resourceOwner.getResourceAsStream(resource)) {
      if (stream == null) {
Evidence
PR Compliance ID 7 requires early validation of required inputs with clear errors; the added method
uses resourceOwner.getResourceAsStream(resource) without any non-null/validity checks, so
missing/invalid inputs can fail later with a non-actionable NPE.

java/src/org/openqa/selenium/io/Read.java[66-68]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`Read.resourceAsString(Class<?>, String)` does not validate required inputs (`resourceOwner`, `resource`) before use, which can lead to runtime `NullPointerException` rather than a clear, actionable error.

## Issue Context
This overload is newly added and is now used by multiple call sites; it should fail fast with a clear message when called incorrectly.

## Fix Focus Areas
- java/src/org/openqa/selenium/io/Read.java[66-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Test uses wrong owner 🐞 Bug ✓ Correctness
Description
ReadTest loads a remote-driver JS resource using Read.class as the resource owner, which is the same
classloader mismatch this PR is meant to fix in OSGi. This test will not validate the new API’s
cross-bundle behavior and would still fail when selenium-io and selenium-remote-driver are separate
bundles.
Code

java/test/org/openqa/selenium/io/ReadTest.java[R45-46]

+    String script = Read.resourceAsString(Read.class, "/org/openqa/selenium/remote/isDisplayed.js");
    assertThat(script).isNotBlank().contains("function(){");
Evidence
Read.class is in the selenium-io module (java/src/org/openqa/selenium/io/BUILD.bazel defines
java_library(name="io")), while isDisplayed.js is packaged as a resource of selenium-remote-driver
(java/src/org/openqa/selenium/remote/BUILD.bazel has resources including ":is-displayed" with out =
"isDisplayed.js"). In OSGi these are different bundles/classloaders, so using Read.class as the
owner would not find /org/openqa/selenium/remote/isDisplayed.js.

java/test/org/openqa/selenium/io/ReadTest.java[43-47]
java/src/org/openqa/selenium/io/BUILD.bazel[1-17]
java/src/org/openqa/selenium/remote/BUILD.bazel[48-56]
java/src/org/openqa/selenium/remote/BUILD.bazel[91-101]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`ReadTest` uses `Read.class` as the `resourceOwner` when loading `/org/openqa/selenium/remote/isDisplayed.js`. In OSGi this will still fail because `Read` (selenium-io bundle) can’t see resources packaged in the selenium-remote-driver bundle.

### Issue Context
The PR adds `Read.resourceAsString(Class<?> resourceOwner, String resource)` specifically to select the correct bundle classloader. The test should therefore use a class that lives in the same module/bundle that owns `/org/openqa/selenium/remote/isDisplayed.js`.

### Fix Focus Areas
- java/test/org/openqa/selenium/io/ReadTest.java[43-47]
- (if needed) java/test/org/openqa/selenium/io/BUILD.bazel[4-14] to add a dependency on a module containing an appropriate owner class

### Suggested change
Replace `Read.class` with a class from the `org.openqa.selenium.remote` module (e.g., `org.openqa.selenium.remote.codec.w3c.W3CHttpCommandCodec.class`), and add the necessary test dependency if compilation requires it.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@asolntsev asolntsev self-assigned this Mar 25, 2026
@asolntsev asolntsev requested a review from diemol March 25, 2026 17:36
@asolntsev asolntsev added I-regression Something was working but we "fixed" it P-bug fix PR addresses a known issue and removed B-devtools Includes everything BiDi or Chrome DevTools related labels Mar 25, 2026
@asolntsev asolntsev added this to the 4.42.0 milestone Mar 25, 2026
…OSGI environment

In OSGi, each bundle has its own classloader that can only see its own resources.

`Read.class.getResource(...)` uses the classloader of the bundle containing class `Read`. It would not  find resource "isDisplayed.js" since it's located in another bundle. The right solution is to use a class from the bundle that owns the resource.
@asolntsev asolntsev force-pushed the fix/17251-resources-in-osgi-environment branch from 22377d6 to 277af8e Compare March 25, 2026 18:41
@asolntsev
Copy link
Copy Markdown
Contributor Author

@diemol Seems that build failure is not related to this PR. Some random JS/Ruby test failures.
Can we merge it to fix #17251 ?

@asolntsev asolntsev merged commit 5d23d81 into SeleniumHQ:trunk Mar 29, 2026
38 of 45 checks passed
@asolntsev asolntsev deleted the fix/17251-resources-in-osgi-environment branch March 29, 2026 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-java Java Bindings I-regression Something was working but we "fixed" it P-bug fix PR addresses a known issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[🐛 Bug]: [java] Resource not found when using ExpectedConditions.visibilityOfElementLocated

3 participants