Hızlı özet, aşağıdakilerden birini yapabilirsiniz:
José'nin cevabına JavaFX modüllerini --module-path
ve --add-modules
benzerlerini ekleyin .
VEYA
Projenize JavaFX kitaplıkları ekledikten sonra (manuel olarak veya maven / gradle içe aktarma yoluyla), module-info.java
dosyayı bu yanıtta belirtilene benzer şekilde ekleyin . (Bu çözümün uygulamanızı modüler hale getirdiğini unutmayın, bu nedenle diğer kitaplıkları kullanırsanız, bunların modüllerinin module-info.java
dosya içinde olmasını gerektirecek ifadeler de eklemeniz gerekir ).
Bu cevap Jose'nin cevabına bir tamamlayıcıdır.
Durum şudur:
- Yeni bir Java sürümünü kullanıyorsunuz, örn. 13.
- Maven projesi olarak bir JavaFX uygulamanız var.
- Maven projenizde, JavaFX eklentisi yapılandırılmış ve Jose'nin cevabına göre JavaFX bağımlılıkları ayarlanmıştır.
- Uygulamayı genişleten ana sınıfınızın kaynak koduna gidersiniz, üzerine sağ tıklayıp çalıştırmayı denersiniz.
- Sen almak bir
IllegalAccessError
uygulamayı başlatmak için çalışırken bir "isimsiz modülü" içeren.
IllegalAccessError
Intellij Idea'dan bir JavaFX uygulamasını çalıştırmaya çalışırken bir yığın izlemesi için alıntı :
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
Tamam, şimdi biraz sıkışmış durumdasın ve neler olduğu hakkında hiçbir fikrin yok.
Gerçekte olan şudur:
- Maven, uygulamanız için JavaFX bağımlılıklarını başarıyla indirdi, bu nedenle bağımlılıkları ayrı ayrı indirmenize veya bir JavaFX SDK veya modül dağıtımı veya benzeri bir şey kurmanıza gerek kalmaz.
- Idea, modülleri projenize bağımlılıklar olarak başarıyla içe aktardı, böylece her şey tamam derlenir ve tüm kod tamamlanır ve her şey yolunda gider.
Görünüşe göre her şey yoluna girmeli. ANCAK, uygulamanızı çalıştırdığınızda, JavaFX modüllerindeki kod, uygulama sınıfınızın (başlatmayı çağırdığınızda) ve FXML denetleyici sınıflarınızın (FXML'yi yüklediğinizde) örneklerini somutlaştırmak için yansımayı kullanmaya çalışırken başarısız oluyor. Biraz yardım olmadan, bu yansıma kullanımı bazı durumlarda başarısız olabilir ve belirsizlik yaratabilir IllegalAccessError
. Bunun nedeni, siz açıkça izin vermediğiniz sürece diğer modüllerden gelen kodun sınıflarınız üzerinde yansıma kullanmasına izin vermeyen bir Java modülü sistem güvenlik özelliğidir (ve JavaFX uygulama başlatıcısı ve FXMLLoader, çalışabilmeleri için her ikisi de mevcut uygulamalarında yansıma gerektirir doğru şekilde).
Referans olan bu soruya verilen diğer cevapların bir kısmı burada module-info.java
devreye giriyor.
Öyleyse Java modüllerinde hızlandırılmış bir kurs alalım:
Anahtar kısım şudur:
4.9. Açık
Özel türlerin yansımasına izin vermemiz gerekiyorsa, ancak tüm kodumuzun açığa çıkmasını istemiyorsak, belirli paketleri açığa çıkarmak için opens yönergesini kullanabiliriz.
Ancak unutmayın, bu paketi tüm dünyaya açacaktır, bu yüzden istediğiniz şeyin bu olduğundan emin olun:
module my.module { opens com.my.package; }
Belki de paketinizi tüm dünyaya açmak istemezsiniz, o zaman şunları yapabilirsiniz:
4.10. Açılır…
Tamam, bu yüzden bazen yansıtma harika, ancak yine de kapsüllemeden elde edebileceğimiz kadar güvenlik istiyoruz. Paketlerimizi önceden onaylanmış bir modül listesine seçerek açabiliriz, bu durumda, open… yönergesini kullanarak:
modül my.module {com.my.package'i moduleOne, moduleTwo, vb. olarak açar; }
Böylece, şuna benzeyen bir src / main / java / module-info.java sınıfı oluşturursunuz:
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;
}
Nerede, org.jewelsea.demo.javafx.springboot
JavaFX Uygulama sınıfı ve JavaFX Denetleyici sınıfları (uygulamanız için uygun paket adıyla bu değiştirin) içeren paketin adıdır. Bu sınıflar için ok olduğunu Java çalışma zamanını anlatır javafx.graphics
ve javafx.fxml
sizin sınıflar üzerinde çağırmak yansıması org.jewelsea.demo.javafx.springboot
paketin. Bu yapıldıktan ve uygulama derlendikten ve yeniden çalıştırıldıktan sonra işler düzgün çalışacak ve IllegalAccessError
JavaFX'in yansıma kullanımı ile oluşturulanlar artık gerçekleşmeyecek.
Peki ya bir module-info.java dosyası oluşturmak istemezseniz
Uygulama sınıfınızı doğrudan çalıştırmak için IDE'nin üst araç çubuğundaki Çalıştır düğmesini kullanmak yerine, bunun yerine:
- IDE'nin yan tarafındaki Maven penceresine gittim.
- Javafx maven eklenti hedefini seçin
javafx.run
.
- Buna sağ tıklayın ve ya
Run Maven Build
da seçimini yapın Debug...
.
Ardından uygulama module-info.java
dosya olmadan çalışacaktır . Sanırım bunun nedeni, maven eklentisinin, uygulamanın bir module-info.java
dosya olmadan bile JavaFX sınıfları tarafından yansıtılmasına izin veren bazı ayarları dinamik olarak içerecek kadar akıllı olmasıdır , ancak bunun nasıl yapıldığını bilmiyorum.
Bu ayarın üst araç çubuğundaki Çalıştır düğmesine aktarılmasını sağlamak için, javafx.run
Maven hedefine sağ tıklayın ve hedef için seçeneğini seçin Create Run/Debug Configuration
. Ardından, Maven hedefini yürütmek için üst araç çubuğundan Çalıştır'ı seçebilirsiniz.