khwang0 / 2018F-COMP3111

19 stars 13 forks source link

[Basic 4] opening URL in native javafx crashes in Ubuntu environment #37

Open bryanchun opened 6 years ago

bryanchun commented 6 years ago

Knowing that we cannot use java.awt.Desktop and its corresponding method to open a URL, I resorted to using javafx.application.HostServices and then hostServices.showDocument to stick with javafx dependency. It works well in my maxOS environment, but java.lang.ClassNotFoundException: com.sun.deploy.uitoolkit.impl.fx.HostServicesFactory is seen from my friend who is using Ubuntu and openJFX. This was experienced by someone on StackOverflow before too: https://stackoverflow.com/a/47997419.

Could you give us advice on what to do? Seems that this is a javafx implementation problem on different platforms. Is this the intended way to open an URL though?

mcreng commented 6 years ago

Here is the stack trace:

java.lang.ClassNotFoundException: com.sun.deploy.uitoolkit.impl.fx.HostServicesFactory
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at com.sun.javafx.application.HostServicesDelegate.lambda$getInstance$0(HostServicesDelegate.java:52)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.HostServicesDelegate.getInstance(HostServicesDelegate.java:45)
    at javafx.application.HostServices.<init>(HostServices.java:52)
    at javafx.application.Application.getHostServices(Application.java:334)
    at comp3111.webscraper.WebScraperApplication.start(WebScraperApplication.java:53)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$5(GtkApplication.java:139)
    at java.lang.Thread.run(Thread.java:748)

The cause is mainly because we do not have com.sun.deploy in non-Oracle Java setups.

cscheungae commented 6 years ago

Knowing that we cannot use java.awt.Desktop and its corresponding method to open a URL, I resorted to using javafx.application.HostServices and then hostServices.showDocument to stick with javafx dependency. It works well in my maxOS environment, but java.lang.ClassNotFoundException: com.sun.deploy.uitoolkit.impl.fx.HostServicesFactory is seen from my friend who is using Ubuntu and openJFX. This was experienced by someone on StackOverflow before too: https://stackoverflow.com/a/47997419.

Could you give us advice on what to do? Seems that this is a javafx implementation problem on different platforms. Is this the intended way to open an URL though?

I want to know how you implement the clickable URL by using the javafx.application.HostServices and hostServices.showDocument? I have google about this. I found that you need to get the hostServices in the Main Application (step A). Then, you can use the showDocument() method. However, when you do step A, you modify the Main Application, which is not allowed to change (project requirement). There is no way to get the hostServices in the controller class where I implement the labelMinPressed function. I have thought of passing the reference of Main Application to the controller class so I can do the clickable link feature in controller class. But, again, the passing involves modification of Main Application. That's why I wonder how you can use javafx.application.HostServices and hostServices.showDocument to deal with the URL link.

mcreng commented 6 years ago

@cscheungae Hi! May I know where it is stated we cannot modify the main application (I assume you meant WebScraperApplication.java)? We may have overlooked.

cscheungae commented 6 years ago

@cscheungae Hi! May I know where it is stated we cannot modify the main application (I assume you meant WebScraperApplication.java)? We may have overlooked.

/* 
     * @see javafx.application.Application#start(javafx.stage.Stage)
     * 
     * This function will be called by the framework shortly after the program started. You are not required to touch any part of this.
     */
    @Override
    public void start(Stage stage) throws Exception {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource(UI_FILE));
        VBox root = (VBox) loader.load();
        Scene scene =  new Scene(root);
        stage.setScene(scene);
        stage.setTitle("WebScrapper");
        stage.show();

    }

The above line is extracted from the WebScraperApplication.java. I am not sure. Are the comment lines telling us that we could not modify the public void start(Stage stage)...?

mcreng commented 6 years ago

Well, in my perspective, not required is not the same as not allowed. I believe we can modify it.

comp3111ta commented 6 years ago

not required is not the same as not allowed.

You should not use java.awt.Desktop in principle. But, in fact you are allowed in this case.

And, in my implementation I neither change the WebApplication nor using java.awt.Desktop. Just JavaFX.