Библиотеки проектов Netbeans - библиотеки времени компиляции и библиотеки времени выполнения - PullRequest
1 голос
/ 19 сентября 2019

Краткое описание

В проекте NetBeans, если я скажу NetBeans, что определенный файл JAR должен быть доступен в компиляции classpath в виде библиотеки, тогда, я понимаю,что NetBeans также сделает этот файл JAR доступным в runpath classpath.Но это «распространение» lib пути к классам, похоже, работает только в немодульном проекте и, по-видимому, не происходит в случае модульного проекта (в Netbeans 11).

Мой эксперимент

Я создал 3 простых экспериментальных проекта, которые называются ProjectA, ProjectB, ProjectC, в Netbeans 11. Среда IDE, а также 3 проекта настроены для работы на Open Jdk12.

ProjectA

ProjectA является немодульным и просто определяет pkg1.MyClassA

ProjectB

ProjectB также является немодульным и определяетpkg2.MyClassB который импортирует и расширяет pkg1.MyClassA.В свойствах ProjectB ==> Библиотеки ==> Компиляция я указал ProjectA/dist/ProjectA.jar файл в качестве обязательной библиотеки пути к классам.В опциях запуска ProjectB (ProjectB Properties ==> Libraries ==> Run) я не указал эту зависимость jar.Во время выполнения потребуется MyClassA, поскольку метод main() для MyClassB создает экземпляр MyClassB, который расширяет MyClassA.

ProjectC

ProjectC является модульным (созданс опцией Netbeans NewProject ==> JavaWithAnd ==> JavaModularProject).Он определяет mod.world/pkg3.MyClassC, который имеет метод main(), который создает экземпляр pkg1.MyClassA.В свойствах ProjectC ==> Библиотеки ==> Компиляция я указал файл ProjectA / dist / ProjectA.jar в качестве обязательной библиотеки пути к классам, так же, как я сделал для зависимости ProjectB от ProjectA.jar.Кроме того, я не указал никакой зависимости jar в свойствах ProjectC ==> Libraries ==> Run, как и в случае свойств ProjectB.Кроме того, я указал --add-reads mod.world=ALL-UNNAMED в параметре компилятора ProjectC, а также параметре JVM времени выполнения, чтобы разрешить явному модулю ProjectC доступ к безымянному модулю ProjectA.jar как во время компиляции, так и во время выполнения.

Опция Compile on save отключена для всех 3 проектов.

Что я ожидал

Я ожидал, что смогу успешно скомпилировать и запустить все 3 проекта.

То, что я на самом деле видел

ProjectA успешно скомпилировано.ProjectB также скомпилировано и успешно запущено.ProjectC скомпилировано успешно, но не удалось во время выполнения с NoClassDefFoundError из-за отсутствия pkg1.MyClassA.Эта ошибка во время выполнения исчезнет, ​​если в свойствах ProjectC ==> Библиотеки ==> Выполнить я укажу ProjectA.jar в качестве обязательной библиотеки пути к классам (как я указал в ProjectC Свойства ==> Библиотеки ==>Компиляция).

Мои вопросы

  1. Диалоговое окно Netbeans в Свойствах проекта ==> Библиотека, говорит:

"Библиотеки времени компиляциираспространяются на все библиотечные категории "

.Я понимаю, что именно по этой причине мне удалось успешно запустить ProjectB, хотя я не указал никакой зависимости jar-файла во время выполнения для ProjectB от ProjectA.jar.Итак, почему же не происходит такое же распространение в случае ProjectC?Это как-то из-за того, что ProjectC является модульным приложением?(Даже если так, почему?).Или это ошибка в Netbeans 11?(Я сделал Google для этого перед публикацией здесь).

Что если в какой-то момент я захочу помешать Netbeans распространять библиотеку времени компиляции во время выполнения или во время тестирования?Есть ли способ сделать это?Для модульных и немодульных проектов?

Вот полный код

Код для ProjectA

package pkg1;

public class MyClassA {
    public MyClassA(){
        System.out.println ("Inside constructor MyClassA()");
    }
}

Код для ProjectB

package pkg2;

import pkg1.MyClassA;

public class MyClassB {
    public MyClassB() {
        new MyClassA();
        System.out.println ("Inside constructor MyClassB()");
    }
    public static void main(String[] args) {
        System.out.println ("Inside main() of MyClassB");
        new MyClassB();
    }
}

Код для ProjectC

Код в module-info.java

module mod.world {
    exports pkg3;
}

Код в MyClassC.java

package pkg3;

import pkg1.MyClassA;

public class MyClassC {

    public static void main(String[] args) {
        new MyClassA();
        System.out.println ("Inside main() method of MyClassC");
    }
}
...