Для изучения Java и сопутствующих технологий я поставил себе задачу: в свободное от работы время переписать рабочий проект с C++/Qt/OSGEarth на Java/NasaWorldWind.
Это позволит мне познакомиться и с Spring, и с Hibernate и Swing/JavaFX и с WorldWind.
Вот мой репозиторий проекта: https://github.com/popov-aa/GeoEditor Прошу не ругать стиль и отсутствие комментариев. Это чисто учебный проект.
Так как версии интерфейсов будет две, Swing и JavaFX, каждый со своим набором бинов, реализующих окна, я решил что в точке входа (класс com.popov.GeoEditor.GeoEditor) будет создаваться основной ApplicationContext, включающий в себя общие бины.
Далее ссылка на этот ApplicationContext в зависимости от аргументов запуска будет передаваться в объект отвечающий за запуск Swing (com.popov.GeoEditor.launcher.SwingLauncher) или JavaFX (com.popov.GeoEditor.launcher.JavaFXLauncher) версий, в которых будет создаваться свой дочерний ApplicationContext.
Когда я запускаю swing-версию никаких проблем нет:
mvn exec:java -Dexec.args="swing"
Когда запускается JavaFX-версия приложения, указатель на родительский ApplicationContext сохраняется как поле класса JavaFXLauncher и после этого запускается javafx.application.Application.
mvn exec:java -Dexec.args="javafx"
Если создавать дочерний ApplicationContext в потоке JavaFX, в методе start, указатель на родительский ApplicationContext уже будет равен null. Бины JavaFX не будут иметь доступа к общим бинам и ничего не запустится. Если создавать дочерний ApplicationContext в основном потоке, в методе, в который передается указатель на общий ApplicationContext, тогда приложение падает из-за попытке создания JavaFX-окон не в JavaFX-потоке, ибо бины не ленивые.
Собственно, вопрос: почему когда запускается JavaFX-поток обнуляется указатель на родительский ApplicationContext (JavaFXLauncher.generalApplicationContext)? Кто его обнуляет?
Я был уверен в том, что объект в Java будет существовать до тех пор, пока на него есть хоть одна ссылка. Ссылку generalApplicationContext я устанавливаю в методе launch(ApplicationContext applicationContext, String[] args) и больше нигде не модифицирую. И вдруг в другом потоке она оказывается равно null.
Есть какие-то правила, касательно того, что связанные друг с другом ApplicationContext должны быть созданы в одном и том же потоке? Я подобной информации не нашел.
И мне казалось, что в Java, в отличие от Qt, нет таких заморочек, ибо отсутствуют встроенные очереди событий.