struct Base {
virtual void f() {}
virtual ~Base() {}
};
struct Derived : Base {
void f() override {}
~Derived() override {}
};
Base* base = new Derived;
base->f(); // calls Derived::f
base->~Base(); // calls Derived::~Derived
Виртуальный вызов деструктора ничем не отличается от любого другого вызова виртуальной функции.
Для base->f()
вызов будет отправляться на Derived::f()
, а для base->~Base()
- то же самое - его функция переопределения - Derived::~Derived()
.
То же самое происходит, когда деструктор называется косвенно, например delete base;
. Оператор delete
вызывает base->~Base()
, который будет отправлен в Derived::~Derived()
.
Если вы не собираетесь удалять объект через указатель на его базовый класс - тогда нет необходимости иметь виртуальный деструктор. Просто сделайте это protected
, чтобы он не был вызван случайно:
// library.hpp
struct Base {
virtual void f() = 0;
protected:
~Base() = default;
};
void CallsF(Base& base);
// CallsF is not going to own "base" (i.e. call "delete &base;").
// It will only call Base::f() so it doesn't need to access Base::~Base.
//-------------------
// application.cpp
struct Derived : Base {
void f() override { ... }
};
int main() {
Derived derived;
CallsF(derived);
// No need for virtual destructor here as well.
}
API-интерфейсы JAXB считаются API-интерфейсами Java EE и поэтому больше не содержатся в пути класса по умолчанию в Java SE 9. В Java 11 они полностью удалены из JDK.
Java 9 вводит понятия модулей, и по умолчанию модуль агрегации java.se
доступен по пути класса (или, скорее, к пути к модулю). Как следует из названия, модуль агрегации java.se
делает not включать Java EE API, которые традиционно были связаны с Java 6/7/8.
К счастью, эти Java EE API-интерфейсы, которые были предоставлены в JDK 6/7/8, все еще находятся в JDK, но по умолчанию они не находятся на пути к классу. Дополнительные API Java EE предоставляются в следующих модулях:
java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation
Быстрое и грязное решение: (только для JDK 9/10) Чтобы API-интерфейсы JAXB были доступны во время выполнения, укажите следующий параметр командной строки : --add-modules java.xml.bind
Но мне все еще нужно это для работы с Java 8 !!! Если вы попробуете указать --add-modules
со старшим JDK, он взорвется, потому что это непризнанный вариант. Я предлагаю один из двух вариантов:
$JAVA_HOME/release
для свойства JAVA_VERSION
. -XX:+IgnoreUnrecognizedVMOptions
, чтобы JVM молча игнорировал непризнанные опции вместо того, чтобы взорваться. Но будьте осторожны! Любые другие аргументы командной строки, которые вы используете, больше не будут проверяться JVM. Эта опция работает с Oracle / OpenJDK, а также с IBM JDK (с JDK 8sr4) Альтернативное быстрое решение: (только JDK 9/10) Обратите внимание, что вы можете сделать все вышеуказанные модули Java EE доступны во время выполнения, указав параметр --add-modules java.se.ee
. Модуль java.se.ee
является агрегатным модулем, который включает в себя java.se.ee
, а также вышеупомянутые модули API Java EE.
Правильное долгосрочное решение: (все версии JDK)
Все перечисленные выше модули API Java EE отмечены @Deprecated(forRemoval=true)
, поскольку они запланированы для удаления в Java 11 . Таким образом, подход --add-module
больше не будет работать в Java 11 из коробки.
Что вам нужно сделать в Java 11 и forward, это включить вашу собственную копию API-интерфейсов Java EE на пути к пути или пути к модулю. Например, вы можете добавить API JAX-B в качестве зависимости от maven следующим образом:
<!-- Java 6 = JAX-B Version 2.0 -->
<!-- Java 7 = JAX-B Version 2.2.3 -->
<!-- Java 8 = JAX-B Version 2.2.8 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
Подробную информацию о модульности Java см. В JEP 261: Система модулей
Ни одно из этих решений не сработало для меня в недавнем JDK 9.0.1.
Я обнаружил, что этого списка зависимостей достаточно для правильной работы, поэтому вам не нужно явно указывать --add-module
(хотя он указан в pom's этих зависимостей). Вам нужно только указать этот список зависимостей:
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
pom.xml
конфигурации Maven. Если вы не знаете, что это такое, тогда лучше начать с начала
– Andremoniy
13 February 2018 в 14:16
<dependency> <groupId>javax.activation</groupId> <artifactId>javax.activation-api</artifactId> <version>1.2.0</version> </dependency>
как последнюю зависимость.
– scrutari
20 April 2018 в 22:58
Чтобы решить эту проблему, я импортировал некоторые JAR-файлы в свой проект:
http://search.maven.org/remotecontent?filepath=javax/xml/bind/jaxb-api/2.3. 0 / jaxb-api-2.3.0.jar
http: //search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-core/2.3.0/jaxb-core-2.3.0.jar
Не ответ, но добавление: я получил, потому что запустил groovysh
(Groovy 2.4.13), если JAVA_HOME указывает на установку Java 9 (точнее, java version "9.0.1"
):
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:564)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:107)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:129)
Caused by: java.lang.NoClassDefFoundError: Unable to load class groovy.xml.jaxb.JaxbGroovyMethods due to missing dependency javax/xml/bind/JAXBContext
at org.codehaus.groovy.vmplugin.v5.Java5.configureClassNode(Java5.java:400)
at org.codehaus.groovy.ast.ClassNode.lazyClassInit(ClassNode.java:277)
at org.codehaus.groovy.ast.ClassNode.getMethods(ClassNode.java:397)
...
..
.
..
...
at org.codehaus.groovy.tools.shell.Groovysh.<init>(Groovysh.groovy:135)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:232)
at org.codehaus.groovy.tools.shell.Main.<init>(Main.groovy:66)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:232)
at org.codehaus.groovy.tools.shell.Main.main(Main.groovy:163)
... 6 more
Решение было:
jaxb-ri-2.3.0.zip
/usr/local/java/jaxb-ri/
). Другое решение может существовать (возможно, через SDKMAN, я dunno) CLASSPATH
. Я делаю это через скрипт, запущенный при запуске bash, называемый /etc/profile.d/java.sh
, где я добавил (среди многих других строк) следующий цикл: Упакован в функцию ...
function extend_qzminynshg {
local BASE="/usr/local/java"
for LIB in jaxb-api.jar jaxb-core.jar jaxb-impl.jar jaxb-jxc.jar jaxb-xjc.jar; do
local FQLIB="$BASE/jaxb-ri/lib/$LIB"
if [[ -f $FQLIB ]]; then
export CLASSPATH=$FQLIB:$CLASSPATH
fi
done
}
extend_qzminynshg; unset extend_qzminynshg
И это работает!
ОК, у меня была такая же проблема, но я использовал java 8 и продолжал получать эту ошибку, я пробовал большинство решений. но оказалось, что мой maven все еще указывал на java 9, хотя я установил глобальную java как 8, поэтому, как только я исправил, что все это сработало, для любого тела, у которого может быть такая проблема, проверьте (How для исправления Maven для использования Java по умолчанию) https://blog.tompawlak.org/maven-default-java-version-mac-osx
После Какие артефакты следует использовать для JAXB RI в моем проекте Maven? в Maven, вы можете использовать такой профиль, как:
<profile>
<id>java-9</id>
<activation>
<jdk>9</jdk>
</activation>
<dependencies>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
</profile>
Дерево зависимостей показывает:
[INFO] +- org.glassfish.jaxb:jaxb-runtime:jar:2.3.0:compile
[INFO] | +- org.glassfish.jaxb:jaxb-core:jar:2.3.0:compile
[INFO] | | +- javax.xml.bind:jaxb-api:jar:2.3.0:compile
[INFO] | | +- org.glassfish.jaxb:txw2:jar:2.3.0:compile
[INFO] | | \- com.sun.istack:istack-commons-runtime:jar:3.0.5:compile
[INFO] | +- org.jvnet.staxex:stax-ex:jar:1.7.8:compile
[INFO] | \- com.sun.xml.fastinfoset:FastInfoset:jar:1.2.13:compile
[INFO] \- javax.activation:activation:jar:1.1.1:compile
Чтобы использовать это в Eclipse, скажем, Oxygen.3a Release (4.7.3a) или позже, Ctrl-Alt-P или щелкните правой кнопкой мыши проект, Maven, затем выберите профиль.
javax.xml.bind
& gt; jaxb-api
, который я видел в другом месте, на самом деле лишний. Зависимость от стеклянной рыбы. Я просто попробовал это, и он действительно работает.
– Basil Bourque
23 July 2018 в 05:42
Вы можете использовать опцию «-add-modules = java.xml.bind» для добавления модуля привязки xml в среду выполнения JVM.
Например: «java --add-modules = java.xml.bind XmlTestClass "
Перейдите в свой Build.gradle и добавьте зависимости ниже для Java 9 или Java 10.
sourceCompatibility = 10 // You can also decrease your souce compatibility to 1.8
//java 9+ does not have Jax B Dependents
compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'
compile group: 'com.sun.xml.bind', name: 'jaxb-core', version: '2.3.0'
compile group: 'com.sun.xml.bind', name: 'jaxb-impl', version: '2.3.0'
compile group: 'javax.activation', name: 'activation', version: '1.1.1'
В моем случае (весенний загрузочный кувшин) я просто добавляю следующее в pom.xml.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
testCompile('javax.xml.bind:jaxb-api')
, работало для меня.
– pamcevoy
17 May 2018 в 15:07
Это сработало для меня:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.0</version>
</dependency>
В качестве зависимостей для моего приложения Java 8, которое создает * .jar, который может выполняться как JRE 8, так и JRE 9 без дополнительных аргументов.
Кроме того, это должно быть выполнено где-то до использования JAXB API:
System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
Пока работает отлично, в качестве обходного пути. Не похоже на идеальное решение, хотя ...
org.eclipse.persistence:eclipselink
только для того, чтобы получить API JAXB - очень тяжелая зависимость, если вы уже не используете eclipselink?
– Andy Guibert
27 September 2017 в 18:59
-XX:+IgnoreUnrecognizedVMOptions
(обновил мой ответ с подробной информацией)
– Andy Guibert
27 September 2017 в 19:55
Это сработало для меня. Добавление только jaxb-api было недостаточно.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
Для Java Web Start Execution мы можем использовать предложение Энди Гвиберта следующим образом:
<j2se version="1.6+"
java-vm-args="-XX:+IgnoreUnrecognizedVMOptions --add-modules=java.se.ee"/>
Обратите внимание на дополнительные «=» в -add-modules. См. этот билет OpenJDK или последнее примечание в разделе «Общие сведения о предупреждениях о доступе к времени» в платформе Java Platform, Standard Edition Oracle JDK 9. .
Во время компиляции, а также времени выполнения добавьте переключатель --add-modules java.xml.bind
javac --add-modules java.xml.bind <java file name>
java --add-modules java.xml.bind <class file>
. Хорошее введение модулей JDK 9
также можно найти по адресу: https: //www.youtube.com/watch?v=KZfbRuvv5qc
java.se.ee
, это действительно шедевр именования. – pvg 23 April 2017 в 17:47javax.xml.bind
и другие классы JavaEE запланированы для удаления в Java 11, за JEP-320 . – Joep Weijers 21 March 2018 в 12:02