eclipse-rap / org.eclipse.rap

Eclipse RAP Runtime (Remote Application Platform)
https://www.eclipse.org/rap/
Eclipse Public License 1.0
17 stars 19 forks source link

Browser Widget: FileNotFoundException under specific conditions / Reduce unnecessary file write actions #198

Open Sebastian-Habenicht opened 2 months ago

Sebastian-Habenicht commented 2 months ago

Setting the same content twice to any Browser widget instance causes an error when the content is > 16KB. This seems not to be RAP, but environment specific, I can reproduce with eclipse 2024-03 (jetty 12.0.6) on Windows (Java17) against the latest RAP code. It does not happen when deployed on Tomcat 9 on Windows, so maybe jetty. The error is

[...] Caused by: java.io.FileNotFoundException: [working directory]\web-app\rwt-resources\org.eclipse.swt.browser\text1042284664.html (The requested operation cannot be performed on a file with a user-mapped section open.) [...] at java.base/java.io.FileOutputStream.open0(Native Method) at org.eclipse.rap.rwt.internal.resources.ResourceManagerImpl.writeResource(ResourceManagerImpl.java:155)

To reproduce:

@Override
  protected void createContents( final Composite shell ) {
    final Browser browser = new Browser( shell, SWT.BORDER );
    browser.setText( createText() );

    final Button b = new Button( shell, SWT.PUSH );
    b.setText( "Set Text" );
    b.addSelectionListener( new SelectionAdapter() {

      @Override
      public void widgetSelected(final SelectionEvent e ) {
        browser.setText( createText() ); 
      }
    } );
  }

  private String createText() {
    final StringBuilder sb = new StringBuilder();
    for( int i = 0; i < 16385; i++ ) { //reduce by 1 to not have the error
      sb.append( "x" );
    }
    return sb.toString();
  }

However, when I checked the ResourceManagerImpl code I was wondering whether the way resources are registered by the BrowserLCA should be adjusted. Currently, the file name is created as a fix prefix "org.eclipse.swt.browser/text" and then the hashCode of the file content is appended. I assume that this is done to have a unique file name for specific HTML content (although hashCode does not guarantee to be unique for Strings in rare cases)?

In this case I would suggest to check in BrowserLCA#registerHtml if the resource is already registered (via ResourceManager#isRegistered) and not register in this case. I have tested this and it prevents such errors as the one described above and also reduces the number of times the file is written on the server when browser widgets with the same content are created.