IntelliJ không thể nhận dạng JavaFX 11 với OpenJDK 11


82

Tôi đang gặp sự cố khi đưa IntellJ nhận dạng các gói JavaFX. Với một dự án JavaFX mới, với OpenJDK 11, khi cố gắng xây dựng dự án, IntelliJ không thể nhận ra các gói JavaFX.

Tôi đã nhập openjfx:javafx-base-11từ kho Maven.

Tôi đã xem xét các câu hỏi khác và các giải pháp dường như bao gồm việc kiểm tra xem mã bytecode có ở mức phù hợp (của tôi là) và ngôn ngữ dự án có đúng không (của tôi là).

Còn ai có ý tưởng nào không?

hình 1

hình 2

hình 3

Biên tập:

Lỗi:

nhập mô tả hình ảnh ở đây


bạn có thể thử từ thiết bị đầu cuối để biên dịch và chạy không?
chết đuối

Bạn sẽ cần phải yêu cầu mô-đun của nó (s) trong bạnmodule-info.java
Jacob G.

Tôi nghĩ bạn cần tạo tác này: mvnrepository.com/artifact/org.openjfx/javafx/11 cái cơ sở không chứa mọi thứ tôi đoán.
Jorn Vernee 23/09/18

@JornVernee khi tôi thử mà tôi gặp lỗi. Tôi đã chỉnh sửa OP với nó.
AlwaysNeedingHelp, 23/09/18

1
Ai nói với bạn điều đó có thể là nhầm lẫn. Bạn cần phải tạo một module-info.javatập tin trong thư mục nguồn của bạn và dứt khoát đòi hỏi bất cứ JavaFX module mà bạn đang sử dụng: requires javafx.controls;, requires javafx.graphics;vv
Jacob G.

Câu trả lời:


128

Như đã đề cập trong các nhận xét, Hướng dẫn Bắt đầu là nơi để bắt đầu với Java 11 và JavaFX 11.

Chìa khóa để làm việc như bạn đã làm trước Java 11 là hiểu rằng:

  • JavaFX 11 không còn là một phần của JDK nữa
  • Bạn có thể nhận được nó ở các hương vị khác nhau, dưới dạng SDK hoặc dưới dạng phụ thuộc thông thường (maven / gradle).
  • Bạn sẽ cần phải đưa nó vào đường dẫn mô-đun của dự án của mình, ngay cả khi dự án của bạn không phải là mô-đun.

Dự án JavaFX

Nếu bạn tạo một dự án mặc định JavaFX thông thường trong IntelliJ (không có Maven hoặc Gradle), tôi khuyên bạn nên tải xuống SDK từ đây . Lưu ý rằng cũng có jmods, nhưng đối với một dự án không mô-đun, SDK được ưu tiên hơn.

Đây là các bước đơn giản để chạy dự án mặc định:

  1. Tạo một dự án JavaFX
  2. Đặt JDK 11 (trỏ tới phiên bản Java 11 cục bộ của bạn)
  3. Thêm JavaFX 11 SDK làm thư viện. URL có thể là một cái gì đó giống như /Users/<user>/Downloads/javafx-sdk-11/lib/. Khi bạn làm điều này, bạn sẽ nhận thấy rằng các lớp JavaFX hiện đã được nhận dạng trong trình soạn thảo.

Dự án JavaFX 11

  1. Trước khi chạy dự án mặc định, bạn chỉ cần thêm chúng vào các tùy chọn VM:

    --module-path /Users/<user>/Downloads/javafx-sdk-11/lib --add-modules=javafx.controls,javafx.fxml

  2. Chạy

Maven

Nếu bạn sử dụng Maven để xây dựng dự án của mình, hãy làm theo các bước sau:

  1. Tạo một dự án Maven với JavaFX archetype
  2. Đặt JDK 11 (trỏ tới phiên bản Java 11 cục bộ của bạn)
  3. Thêm các phụ thuộc JavaFX 11.

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>11</version>
        </dependency>
    </dependencies>
    

Khi bạn làm điều này, bạn sẽ nhận thấy rằng các lớp JavaFX hiện đã được nhận dạng trong trình soạn thảo.

Dự án JavaFX 11 Maven

Bạn sẽ nhận thấy rằng Maven quản lý các phụ thuộc cần thiết cho bạn: nó sẽ thêm javafx.base và javafx.graphics cho javafx.controls, nhưng quan trọng nhất, nó sẽ thêm bộ phân loại bắt buộc dựa trên nền tảng của bạn. Trong trường hợp của tôi, Mac.

Đây là lý do tại sao bình của bạn org.openjfx:javafx-controls:11trống rỗng , bởi vì có ba phân loại tốt (cửa sổ, Linux và Mac nền tảng), có chứa tất cả các lớp học và việc thực hiện bản xứ.

Trong trường hợp bạn vẫn muốn truy cập repo .m2 của mình và lấy các phần phụ thuộc từ đó theo cách thủ công, hãy đảm bảo bạn chọn đúng (ví dụ .m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-mac.jar)

  1. Thay thế các plugin maven mặc định bằng các plugin từ đây .

  2. Chạy mvn compile javafx:run, và nó sẽ hoạt động.

Các hoạt động tương tự cũng đối với các dự án Gradle, như được giải thích chi tiết ở đây .

BIÊN TẬP

Hướng dẫn Bắt đầu được đề cập chứa tài liệu cập nhật và các dự án mẫu cho IntelliJ:


1
Đường dẫn là một cái gì đó giống như /Users/<user>/Downloads/javafx-sdk-11/lib/, thông báo libthư mục. Điều đó sẽ chứa tất cả các lọ JavaFX
José Pereda

5
Nếu bất kỳ ai gặp sự cố với đường dẫn mô-đun, họ cần phải trông giống như thế này trên windows: --module-path = "C: \ Path \ To \ Your \ JavaFX \ lib" --add-modules = javafx.controls, javafx .fxml, javafx.base, javafx.media, javafx.graphics, javafx.swing, javafx.web Lưu ý dấu "=" và cả dấu ngoặc kép xung quanh nó. Điều này đã hiệu quả với tôi trong khi bất kỳ cách tiếp cận nào khác thì không. Hơn nữa, hãy nhớ rằng tham số -jar YourJar.jar cần phải đến SAU KHI đường dẫn mô-đun và các tùy chọn bổ sung mô-đun.
Jalau

4
Xin chào @ JoséPereda. Tôi đã gặp khó khăn với hướng dẫn này kể từ một thời gian, nhưng tôi thực sự không thể làm cho IntelliJ chạy mã của tôi, ngay cả khi tôi đã làm chính xác những gì bạn đã viết. Tôi vẫn nhận được "Lỗi: java: không tìm thấy mô-đun: javafx.fxml", v.v. Bất kỳ cơ hội để trò chuyện riêng tư để giúp tôi giải quyết vấn đề này? Cảm ơn bạn.
Davide3i

1
@jalau cảm ơn bạn! các trích dẫn thực sự đã làm điều đó, bạn nên viết điều này như một câu trả lời.
derfect

2
Khi tôi xây dựng phân phối cho dự án mẫu cho Gradle và sau đó chạy nó, tôi nhận được thông báo lỗi: "Lỗi: thành phần thời gian chạy JavaFX đang mất tích, và được yêu cầu để chạy ứng dụng này"
Trejkaz

9

Vấn đề là JavaFX không còn là một phần của JDK 11. Giải pháp sau hoạt động bằng cách sử dụng IntelliJ (chưa thử với NetBeans):

  1. Thêm Thư viện toàn cầu JavaFX làm phần phụ thuộc:

    Cài đặt -> Cấu trúc dự án -> Mô-đun. Trong mô-đun, hãy chuyển đến tab Phụ thuộc và nhấp vào dấu "+" thêm -> Thư viện -> Java-> chọn JavaFX từ danh sách và nhấp vào Thêm đã chọn, sau đó áp dụng cài đặt.

  2. Nhấp chuột phải vào tệp nguồn (src) trong dự án JavaFX của bạn và tạo tệp module-info.java mới . Bên trong tệp, viết mã sau:

    module YourProjectName { 
        requires javafx.fxml;
        requires javafx.controls;
        requires javafx.graphics;
        opens sample;
    }
    

    2 bước này sẽ giải quyết tất cả các vấn đề của bạn với JavaFX, tôi đảm bảo với bạn.

Tham khảo: Có một bài hướng dẫn You Tube do kênh Học Lập trình thực hiện, sẽ giải thích tất cả các chi tiết trên chỉ trong 5 phút. Tôi cũng khuyên bạn nên xem nó để giải quyết vấn đề của bạn: https://www.youtube.com/watch?v=WtOgoomDewo


8

Không có điều nào ở trên phù hợp với tôi. Tôi đã dành quá nhiều thời gian để xóa các lỗi khác phát sinh. Tôi thấy đây là cách dễ nhất và tốt nhất.

Điều này hoạt động để tải JavaFx trên Jdk 11, 12 và trên OpenJdk12 nữa!

  • Video hiển thị cho bạn tải xuống JavaFx Sdk
  • Cách đặt nó làm Thư viện toàn cầu
  • Đặt module-info.java (tôi thích cái dưới cùng hơn)

module thisIsTheNameOfYourProject {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.graphics;
    opens sample;
}

Toàn bộ điều tôi mất chỉ 5 phút !!!


Đặt nó làm thư viện toàn cầu đã được chuyển vào năm 2019. Bạn có thể chỉ ra nơi này nằm ở đâu không?
Michael S.

Cảm ơn rất nhiều! Cũng làm việc cho tôi !!! Ủng hộ!
Daniel Boehm

4

Tóm tắt nhanh, bạn có thể thực hiện:

  1. Bao gồm các mô-đun JavaFX thông qua --module-path--add-modulesgiống như trong câu trả lời của José.

    HOẶC LÀ

  2. Sau khi bạn đã thêm thư viện JavaFX vào dự án của mình (theo cách thủ công hoặc thông qua nhập maven / gradle), hãy thêm module-info.javatệp tương tự như tệp được chỉ định trong câu trả lời này. (Lưu ý rằng giải pháp này làm cho ứng dụng của bạn có dạng mô-đun, vì vậy nếu bạn sử dụng các thư viện khác, bạn cũng sẽ cần thêm các câu lệnh để yêu cầu mô-đun của chúng bên trong module-info.javatệp).


Câu trả lời này là một bổ sung cho câu trả lời của Jose.

Tình hình là thế này:

  1. Bạn đang sử dụng phiên bản Java gần đây, ví dụ: 13.
  2. Bạn có một ứng dụng JavaFX dưới dạng một dự án Maven.
  3. Trong dự án Maven của bạn, bạn đã định cấu hình plugin JavaFX và thiết lập các phụ thuộc JavaFX theo câu trả lời của Jose.
  4. Bạn đi tới mã nguồn của lớp chính mở rộng Ứng dụng, bạn nhấp chuột phải vào nó và thử chạy nó.
  5. Bạn nhận được IllegalAccessErrorliên quan đến một "mô-đun không tên" khi cố gắng khởi chạy ứng dụng.

Đoạn trích cho dấu vết ngăn xếp tạo ra IllegalAccessErrorkhi cố gắng chạy ứng dụng JavaFX từ Intellij Idea:

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x45069d0e) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module @0x45069d0e
    at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
    at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)
    at org.jewelsea.demo.javafx.springboot.Main.start(Main.java:13)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
Exception running application org.jewelsea.demo.javafx.springboot.Main

OK, bây giờ bạn đang bị mắc kẹt và không có manh mối gì đang xảy ra.

Điều đã thực sự xảy ra là:

  1. Maven đã tải xuống thành công các phụ thuộc JavaFX cho ứng dụng của bạn, vì vậy bạn không cần tải xuống riêng các phụ thuộc hoặc cài đặt JavaFX SDK hoặc phân phối mô-đun hoặc bất kỳ thứ gì tương tự.
  2. Idea đã nhập thành công các mô-đun dưới dạng phụ thuộc vào dự án của bạn, vì vậy mọi thứ biên dịch OK và tất cả các mã hoàn thành và mọi thứ hoạt động tốt.

Vì vậy, có vẻ như mọi thứ sẽ ổn. NHƯNG, khi bạn chạy ứng dụng của mình, mã trong mô-đun JavaFX không thành công khi cố gắng sử dụng phản chiếu để khởi tạo các phiên bản của lớp ứng dụng của bạn (khi bạn gọi khởi chạy) và các lớp bộ điều khiển FXML của bạn (khi bạn tải FXML). Nếu không có một số trợ giúp, việc sử dụng phản xạ này có thể không thành công trong một số trường hợp, tạo ra sự che khuất IllegalAccessError. Điều này là do tính năng bảo mật hệ thống mô-đun Java không cho phép mã từ các mô-đun khác sử dụng phản chiếu trên các lớp của bạn trừ khi bạn cho phép rõ ràng (và trình khởi chạy ứng dụng JavaFX và FXMLLoader đều yêu cầu phản ánh trong quá trình triển khai hiện tại của chúng để chúng hoạt động đúng).

Đây là nơi mà một số câu trả lời khác cho câu hỏi này, tài liệu tham khảo module-info.java, đi vào hình ảnh.

Vì vậy, chúng ta hãy tham gia một khóa học về lỗi trong các mô-đun Java:

Phần quan trọng là:

4.9. Mở cửa

Nếu chúng ta cần cho phép phản ánh các loại private, nhưng chúng ta không muốn tất cả mã của mình bị lộ, chúng ta có thể sử dụng lệnh opens để hiển thị các gói cụ thể.

Nhưng hãy nhớ rằng, điều này sẽ mở gói cho toàn bộ thế giới, vì vậy hãy đảm bảo đó là những gì bạn muốn:

module my.module { opens com.my.package; }

Vì vậy, có lẽ bạn không muốn mở gói của mình cho toàn thế giới, thì bạn có thể làm:

4.10. Mở… Tới

Được rồi, đôi khi phản xạ là rất tốt, nhưng chúng tôi vẫn muốn bảo mật nhiều nhất có thể từ việc đóng gói. Chúng tôi có thể mở một cách chọn lọc các gói của mình theo danh sách các mô-đun đã được phê duyệt trước, trong trường hợp này, sử dụng lệnh opens… to:

module my.module {mở com.my.package thành moduleOne, moduleTwo, v.v.; }

Vì vậy, bạn kết thúc việc tạo một lớp src / main / java / module-info.java trông giống như sau:

module org.jewelsea.demo.javafx.springboot {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.graphics;
    opens org.jewelsea.demo.javafx.springboot to javafx.graphics,javafx.fxml;
}

Ở đâu, org.jewelsea.demo.javafx.springbootlà tên của gói chứa lớp Ứng dụng JavaFX và các lớp Bộ điều khiển JavaFX (thay thế tên này bằng tên gói thích hợp cho ứng dụng của bạn). Điều này cho người chạy Java biết rằng các lớp trong javafx.graphicsjavafx.fxmlgọi phản chiếu trên các lớp trong org.jewelsea.demo.javafx.springbootgói của bạn là được . Khi điều này được thực hiện, và ứng dụng được biên dịch và chạy lại, mọi thứ sẽ hoạt động tốt và việc IllegalAccessErrortạo ra bởi việc sử dụng phản chiếu của JavaFX sẽ không còn xảy ra nữa.

Nhưng nếu bạn không muốn tạo tệp module-info.java

Nếu thay vì sử dụng nút Run trong thanh công cụ trên cùng của IDE để chạy trực tiếp lớp ứng dụng của bạn, bạn thay vào đó:

  1. Đã đến cửa sổ Maven ở bên cạnh IDE.
  2. Chọn mục tiêu plugin javafx maven javafx.run.
  3. Nhấp chuột phải vào đó và chọn một trong hai Run Maven Buildhoặc Debug....

Sau đó, ứng dụng sẽ chạy mà không có module-info.javatệp. Tôi đoán điều này là do plugin maven đủ thông minh để bao gồm động một số loại cài đặt cho phép ứng dụng được các lớp JavaFX phản ánh ngay cả khi không có module-info.javatệp, mặc dù tôi không biết điều này được thực hiện như thế nào.

Để chuyển cài đặt đó sang nút Run trên thanh công cụ trên cùng, hãy nhấp chuột phải vào javafx.runmục tiêu Maven và chọn tùy chọn Create Run/Debug Configurationcho mục tiêu. Sau đó, bạn chỉ có thể chọn Run từ thanh công cụ trên cùng để thực hiện mục tiêu Maven.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.