Я использую Java 11 (AdoptOpenJDK 11.0.5 2019-10-15) на Windows 10. У меня есть несколько устаревших файлов X HTML 1.1, которые я хочу обработать. Они принимают следующую общую форму:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>XHTML 1.1 Skeleton</title>
</head>
<body>
</body>
</html>
Чтобы парсер не ожидал подключения к Inte rnet, я устанавливаю пользовательский EntityResolver
, который загружает известные сущности (из их идентификаторов publi c, например -//W3C//ELEMENTS XHTML Inline Style 1.0//EN
), хранящиеся в ресурсах программы. Этот класс DefaultEntityResolver
также печатает сообщения отладки, указывающие, какие объекты загружается анализатором.
Вот базовая форма c моего анализа:
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
documentBuilder.setEntityResolver(DefaultEntityResolver.getInstance());
final Document document;
try (InputStream inputStream = new BufferedInputStream(getClass().getResourceAsStream("xhtml-1.1-test.xhtml"))) {
document = documentBuilder.parse(inputStream);
}
Из-за сообщений отладки в DefaultEntityResolver
, я вижу, что синтаксический анализатор загрузил следующие объекты, в этом порядке.
Примечание что некоторые из этих объектов больше не существуют по указанному URL; тем не менее в моем DefaultEntityResolver
эти сущности уже сохранены и привязаны к их опубликованным идентификаторам c, и, таким образом, они все еще передаются парсеру.
Пока все хорошо. Но когда я немедленно вызываю document.normalizeDocument()
, программа приостанавливает и затем печатает:
[Error] xhtml11.dtd:129:43: The entity "LanguageCode.datatype" was referenced, but not declared.
[Error] xhtml11.dtd:130:44: The entity "LanguageCode.datatype" was referenced, but not declared.
[Error] xhtml11.dtd:194:47: The entity "Common.attrib" was referenced, but not declared.
Обратите внимание, что это не моя программа, печатающая эти ошибки; это явно что-то внутри document.normalizeDocument()
. Кроме того, есть еще два любопытства:
- Этого не происходит, если я запускаю свое приложение из Eclipse.
- Этого не происходит, если я отключаю сетевое соединение.
По-моему, document.normalizeDocument()
не использует пользовательский EntityResolver
, установленный в конструкторе документов. Поскольку некоторые из сущностей больше не существуют по их ожидаемым URL-адресам (например, http://www.w3.org/TR/xhtml11/DTD/xhtml-datatypes-1.mod
), они не могут быть загружены, и поэтому указанные ссылочные сущности никогда не будут определены. Однако веб-серверу требуется много времени, чтобы ответить, что сущности отсутствуют (как вы можете проверить вручную), что заставляет программу приостановиться. Это также может объяснить, почему сообщения об ошибках не появляются, когда мое сетевое соединение отключено; Я предполагаю, что ни один внешних объектов не может быть загружен, немедленно завершается неудачей, но это не считается ошибкой. (Ничто из этого не объясняет, почему это работает без паузы или сообщения об ошибке внутри Eclipse.)
На самом деле DOMConfiguration
документация подсказывает, что мне нужно установить какой-то resource-resolver
параметр, хотя я не уверен, почему DOMConfiguration
не используется по умолчанию для распознавателя сущностей, который я установил в исходном конструкторе документов, который использовался для анализа документа XML.
Чтобы сделать вещи немного страннее, Я поместил скелет X HTML 1.1, указанный выше, в мои ресурсы и создал модульный тест, точно такой же, как и код выше, затем document.normalizeDocument()
, и тест прошел без пауз и ошибок, даже из команды line !
Но тогда, если я добавлю al oop for(int i = 0; i < 100; i++)
в модульный тест; загрузить, проанализировать и нормализовать документ 100 раз (но с использованием того же DocumentBuilderFactory
); мой юнит тест полностью разбивает JVM раздвоенного юнит теста !!
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.1:test (default-test) on project [...]: There are test failures.
Please refer to [...]\xml\target\surefire-reports for the individual test results.
Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
Command was cmd.exe /X /C [...]
Process Exit Code: 0
Crashed tests:
[...].XmlDomTest
org.apache.maven.surefire.booter.SurefireBooterForkException: The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
Command was cmd.exe /X /C [...]
Process Exit Code: 0
Crashed tests:
com.globalmentor.xml.XmlDomTest
at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:669)
at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:282)
at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:245)
at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1183)
at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1011)
at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:857)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:193)
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:566)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:566)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: org.apache.maven.plugin.MojoExecutionException: There are test failures.
Так что я думаю, что хочу избежать document.normalizeDocument()
, но я приветствую любые разъяснения этого поведения.