Vscode-java: JavaFX application produce warning

Created on 17 Dec 2016  路  36Comments  路  Source: redhat-developer/vscode-java

A lot of warnings about restricted API

Environment
  • Operating System: Windows 10 64-bit
  • JDK version: jdk1.8.0_111
  • Visual Studio Code version: 1.8
  • Java extension version: 0.0.7
Steps To Reproduce
  1. Create JavaFX hello world
  2. Open project in VS Code
  3. Open HelloWorld.java
Current Result

All code has following hints:

[Java] Access restriction: The type 'Application' is not API (restriction on required library 'C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\jfxrt.jar')
Expected Result

No hints provided, or some configuration option needed to override restricted libraries.

enhancement

Most helpful comment

@tomsontom That's a good solution, but unfortunately there are projects that rely on JDK 8 and won't update anytime soon.

Having to re-add

<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/">
    <accessrules>
        <accessrule kind="accessible" pattern="javafx/**"/>
        <accessrule kind="accessible" pattern="com/sun/javafx/**"/>
    </accessrules>
</classpathentry>

every time the project changes structurally is tedious and should be fixed.

All 36 comments

same here add an image of warning.
virtualbox_xubu_09_01_2017_14_02_12

Technically the libraries from extension classpath are not guaranteed to exist on JVMs so they are restricted. I think we need to introduce a setting to suppress these warnings.

@gorkem is there any specific location in code where I could look to implement this ? I treat any warning as errors and having that warnings don't allow me keep track of other warnings

You can have a workaround by adding access rules to the .classpath files. This has an example of how to add JavaFX entries and maintaining them.

@gorkem we should probably provide a quick fix that performs that change in the access rules automagically

any update on this ?

javafx.scene.layout.VBox vb = new javafx.scene.layout.VBox();

produces a red underline with the following error message

[Java] Access restriction: The type 'VBox' is not API (restriction on required library 'C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\jfxrt.jar')

autocomplete does seem to still work tho. i just would really need a setting to simply ignore this error.

As the author of e(fx)clipse I had to fix the same problems you see for the Eclipse IDE. There are in fact 2 things to consider for JavaFX

  • it's a library from the ext-folder
  • it's source is not part of rt-src.zip

What we do in e(fx)clipse is that we use a JDT-Extension-Point to configure the VMInstall to:

  • contain the correct accessibility rules
  • add the source-path for javafx-rt.zip

You can see our code at

# Access restriction: The type 'Platform' is not API (restriction on required library '/usr/lib/jvm/java-8-oracle/jre/lib/ext/jfxrt.jar')
...
_Solution?_

Bumping this again to see if a solution has been found. Sure it compiles fine but the errors in the IDE are a little annoying.

Seeing this too for jdk.nashorn. No idea why it's restricted. Really need a setting on the plugin to suppress these errors.

As a workaround, to get rid of theses warnings, you can add org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore to your <project>/.settings/org.eclipse.jdt.core.prefs. You'll need to install the latest CI build for this modification to reach the java language server (#239).

@joewood see @gorkem's explanation about the restriction.

Any updates on this thread? I'm working with the workaround but it would be nice to have an official fix.

+1

276 gets closed because of this, this gets closed because of #276.. doesn't seem like a solution will come up.. +1

Any updates the status of this? I am running the latest Oracle Java 8, latest VS Code, and downloaded the CI build of the plugin yet still have this problem. I tried the 'workaround' (org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore) but that didn't work for me either. Here is what I have as far as build is concerned.

/.settings/org.eclipse.buildship.core.prefs

auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
offline.mode=false
override.workspace.settings=true
org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore

/.classpath

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="bin/main" path="src">
        <attributes>
            <attribute name="gradle_scope" value="main"/>
            <attribute name="gradle_used_by_scope" value="main,test"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="src" output="bin/main" path="resources">
        <attributes>
            <attribute name="gradle_scope" value="main"/>
            <attribute name="gradle_used_by_scope" value="main,test"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
    <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
    <classpathentry kind="output" path="bin/default"/>
</classpath>

/.project

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>MyProject</name>
    <comment>Project MyProject created by Buildship.</comment>
    <projects>
    </projects>
    <buildSpec>
        <buildCommand>
            <name>org.eclipse.jdt.core.javabuilder</name>
            <arguments>
            </arguments>
        </buildCommand>
        <buildCommand>
            <name>org.eclipse.buildship.core.gradleprojectbuilder</name>
            <arguments>
            </arguments>
        </buildCommand>
    </buildSpec>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
        <nature>org.eclipse.buildship.core.gradleprojectnature</nature>
    </natures>
</projectDescription>

/build.gradle

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java project to get you started.
 * For more details take a look at the Java Quickstart chapter in the Gradle
 * user guide available at https://docs.gradle.org/4.10/userguide/tutorial_java_projects.html
 */

plugins {
    // Apply the java plugin to add support for Java
    id 'java'

    // Apply the application plugin to add support for building an application
    id 'application'
}

compileJava {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

// Define the main class for the application
mainClassName = 'MyClass'

dependencies {
    // This dependency is found on compile classpath of this component and consumers.
    compile 'com.google.guava:guava:23.0'

    // Use JUnit test framework
    testCompile 'junit:junit:4.12'
}

// In this section you declare where to find the dependencies of your project
repositories {
    // Use jcenter for resolving your dependencies.
    // You can declare any Maven/Ivy/file repository here.
    jcenter()
}

sourceSets {
    main {
        java {
            srcDir 'src'
        }
        resources {
            srcDir 'resources'
        }
    }
}

/.vscode/settings.json

{
    "java.configuration.updateBuildConfiguration": "automatic"
}

I'm building a basic JavaFX example from Oracle's samples.

I tried the 'workaround' (org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore) but that didn't work for me either. Here is what I have as far as build is concerned.

/.settings/org.eclipse.buildship.core.prefs

.settings/org.eclipse.jdt.core.prefs

...
org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore
...

@snjeza Oh wow, I totally missed the paths in between. I didn't see that file in .settings, so I created it but I am still seeing the error. Is that file automatically read or do I have to point a var to it?

@primesoftware try to restart VS Code

@snjeza Still doing the same thing after restart. This is really puzzling. Are there any cache files that may be prioritized over the files in .settings?

Are there any cache files that may be prioritized over the files in .settings?

@primesoftware No, there aren't any files.
You can try to clean your workspace - https://github.com/redhat-developer/vscode-java/wiki/Troubleshooting#clean-the-workspace-directory

@snjeza That did it!!! No more nasty red underlines! Any thoughts as to why the workspace needed to be cleared?

@primesoftware
are you able to use code completion for Javafx
I was creating Button object of javafx control but the VSCode is not giving the suggestion for Javafx control instead it gives suggestion of AWT Button

@ESLHemantSangle I had it working, but I'm having .classpath issues now since I switched to using Gradle's new .kts build scripts.

Any progress on this issue?

Editing .settings/org.eclipse.jdt.core.prefs disables the error messages, but does not provide code completion for JavaFX types.

Adding access rules to .classpath works temporarily (even with code completion), but resets every time the configuration is synchronized:

image

It would be really useful to have official JavaFX support for this in the extension, considering that it's the standard GUI toolkit.

Starting with Java-11 - It is an ordinary library you add simply as a maven dependency so the problem solves itself

@tomsontom That's a good solution, but unfortunately there are projects that rely on JDK 8 and won't update anytime soon.

Having to re-add

<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/">
    <accessrules>
        <accessrule kind="accessible" pattern="javafx/**"/>
        <accessrule kind="accessible" pattern="com/sun/javafx/**"/>
    </accessrules>
</classpathentry>

every time the project changes structurally is tedious and should be fixed.

A better solution for using JavaFX with JDK 8, is to integrate the access rule directly into build.gradle using the eclipse plugin:

import org.gradle.plugins.ide.eclipse.model.AccessRule

apply plugin: 'java'
apply plugin: 'eclipse'

eclipse {
    classpath {
        file {
            whenMerged {
                def jre = entries.find { it.path.contains 'org.eclipse.jdt.launching.JRE_CONTAINER' }
                jre.accessRules.add(new AccessRule('0', 'javafx/**'))
                jre.accessRules.add(new AccessRule('0', 'com/sun/javafx/**'))
            }
        }
    }
}

That way the .classpath is not "fragile" anymore and the project configuration updates correctly automatically.

Any update on this issue? I'm still running into @fwcd 's problem: it's very annoying to manually add access rules to the pom.xml of Java 8 projects. Is there any plan to allow some form of configuration so that JavaFX in Oracle's JDK 8 plays nicely with this extension?

So I tried @tomsontom's solution of automatically relaxing the access rules when javafx is detected in the JDK, by copying a bunch of e(fx)clipse classes to JDT.LS.
It works for Oracle JDK 1.8 and Liberica 8.0.265.FX. Other JDK 8 distros that don't ship Java FX obviously can't compile the project.

So, what next? Anything else I'd need to do to ensure JavaFX support is acceptable? (I have zero interest in Java FX myself so please enlighten me).

Well the question is could efxclipse restructure its codebase and deliver an extension one can optionally install into jdt.ls

Anyone willing to test my changes can manually install this vsix file in vscode: https://dl.bintray.com/fbricon/vscode-extensions/vscode-java/redhat.java-0.66.999.vsix

@tomsontom if you can provide an eclipse plugin containing just those files: https://github.com/eclipse/eclipse.jdt.ls/pull/1536, then I can remove them from jdt.ls and use it directly. I don't think it's worth having another 3rd party vscode extension just for this basic JavaFX support.

@fbricon your custom vscode-java plugin fixed the issue for me, thanks! (I'm running on Oracle JDK 8u191).

@fbricon I guess the problem is that efxclipse dropped from the release train hence adopting would not be so simple for you and given the JDK-8 will be used less and less I guess it is not worth the effort

Since RedHat is pushing out new updates without adding JavaFX support, I made a quick extension for Java 8 users that automatically adds the <accessrule> necessary to suppress API warnings whenever .classpath is updated in the project configuration. It's available here if anyone would like to use it:

https://marketplace.visualstudio.com/items?itemName=shrey150.javafx-support

Fixed with https://github.com/eclipse/eclipse.jdt.ls/pull/1536. Will be released tomorrow.

Thank you for fixing this!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BuZZ-dEE picture BuZZ-dEE  路  4Comments

bilymed picture bilymed  路  3Comments

gorkem picture gorkem  路  4Comments

sfariaNG picture sfariaNG  路  3Comments

shawmanz32na picture shawmanz32na  路  3Comments