iText XFA Работник по OSGI (Караф)
В настоящее время я пытаюсь развернуть решение отрисовки форм XFA для Karaf. Весь мой код прекрасно работает при локальном тестировании (без OSGi), но когда я пытаюсь выполнить развертывание в Karaf, я получаю различные ошибки. Я полагаю, что основная причина заключается в том, что файлы XFAWorker не скомпилированы как пакеты OSGi. Поэтому я использовал протокол обертывания Karaf для импорта пакетов, но все еще не удается. Я попробовал довольно много вещей и постараюсь документировать их как можно более подробно ниже. Тем не менее, описать различные препятствия, с которыми я сталкиваюсь, очень долго, поэтому в простом выражении краткий обзор моих вопросов:
Как можно использовать iText XFA Worker в контейнере OSGi? (Караф / Феликс предпочтительно)
При этом полная печальная история того, что я пробовал:
Во-первых, фрагмент кода, который требует использования рабочих файлов XFA:
private byte[] flattenXfa(byte[] sourceXfaBytes) throws RuntimeException {
// Create an output stream for the flattened doc
ByteArrayOutputStream flattened = new ByteArrayOutputStream();
try {
Document document = new Document();
PdfReader reader = new PdfReader(sourceXfaBytes);
PdfWriter writer = PdfWriter.getInstance(document, flattened);
XFAFlattener flattener = new XFAFlattener(document, writer);
flattener.flatten(reader);
document.close();
} ... various catches
}
Этот метод вызывается (через другой класс) в методе запуска моего активатора пакета, так что это означает, что я пытаюсь отобразить (и выровнять) PDF при запуске пакета. Это действительно просто для целей тестирования - мы создали совершенно отдельный проект, который на самом деле просто имеет небольшой пакет и код рендеринга, чтобы убедиться, что ничто другое не может вызвать проблемы.
Вот метод запуска моего активатора (на всякий случай, если это важно)
public void start(BundleContext context) {
System.out.println("Starting the bundle");
System.out.println("Rendering PDF");
Renderer rend = new Renderer();
String templatePath = "Path/to/xfa/file";
String renderPayload = "<form1><Name>MyName</Name><Surname>MySurname</Surname></form1>";
String xfaPdfPath = "Path/to/output/interactive/form";
String flatPdfPath = "Path/to/output/flat/pdf";
String licenseFilePath = "Path/to/itext/license/file";
boolean flatten = true;
rend.renderDoc(flatten, templatePath, renderPayload, xfaPdfPath, flatPdfPath, licenseFilePath);
}
Как видите, у меня есть логический флаг, который позволяет мне пропустить метод flattenXfa при определенных обстоятельствах.
В моем Maven POM я использую следующие зависимости:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xfaworker</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>itext-licensekey</artifactId>
<version>1.0.4</version>
</dependency>
Обратите внимание: jar-файлы itextpdf и xmlworker доступны в виде пакетов OSGi. Только xfaworker и itext-licensekey вызывают проблемы
Как было сказано ранее, когда я запускаю код вне OSGi, он работает нормально - он рендерит и выравнивает PDF как чемпион.
Когда я пытаюсь запустить из OSGi, это вызывает различные проблемы, в зависимости от моего подхода. Итак, вот след из вещей, которые я пробовал. Я объясню, какие проблемы у меня возникают с каждым:
Попробуйте 1: Используйте протокол Wrap для установки не OSGi комплектов.
После запуска Karaf я последовательно запускаю следующие команды, то есть моделирую, что будет делать мой конечный файл объектов:
bundle:install -s mvn:com.itextpdf/itextpdf/5.5.11
bundle:install -s mvn:com.itextpdf.tool/xmlworker/5.5.11
bundle:install -s wrap:mvn:com.itextpdf.tool/xfaworker/5.5.11
bundle:install -s wrap:mvn:com.itextpdf.tool/itext-licensekey/1.0.4
bundle:install mvn:com.testing/xfa-test/0.0.1-SNAPSHOT (I specifically don't start it yet)
Когда я начинаю свой пакет, я получаю следующую проблему:
Starting the bundle
Rendering PDF
java.lang.NoClassDefFoundError: com/itextpdf/tool/xml/html/CssAppliersAware
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.defineClass(BundleWiringImpl.java:2370)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2154)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1542)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1415)
at org.apache.felix.framework.BundleWiringImpl.searchImports(BundleWiringImpl.java:1595)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1525)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at com.testing.xfa.Renderer.flattenXfa(Renderer.java:123)
at com.testing.xfa.Renderer.renderDoc(Renderer.java:52)
at com.testing.xfa.Activator.start(Activator.java:34)
at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:697)
at org.apache.felix.framework.Felix.activateBundle(Felix.java:2226)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2144)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998)
at org.apache.karaf.bundle.command.Start.executeOnBundle(Start.java:38)
at org.apache.karaf.bundle.command.BundlesCommand.doExecute(BundlesCommand.java:64)
at org.apache.karaf.bundle.command.BundlesCommand.execute(BundlesCommand.java:54)
at org.apache.karaf.shell.impl.action.command.ActionCommand.execute(ActionCommand.java:83)
at org.apache.karaf.shell.impl.console.osgi.secured.SecuredCommand.execute(SecuredCommand.java:67)
at org.apache.karaf.shell.impl.console.osgi.secured.SecuredCommand.execute(SecuredCommand.java:87)
at org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:480)
at org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:406)
at org.apache.felix.gogo.runtime.Pipe.run(Pipe.java:108)
at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:182)
at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:119)
at org.apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.java:94)
at org.apache.karaf.shell.impl.console.ConsoleSessionImpl.run(ConsoleSessionImpl.java:274)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: com.itextpdf.tool.xml.html.CssAppliersAware not found by wrap_mvn_com.itextpdf.tool_xfaworker_5.5.11 [61]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1574)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 35 more
Error executing command: Error executing command on bundles:
Error starting bundle 65: Activator start error in bundle xfa-test [65].
Ради интереса, если я установил атрибут flatten в false (то есть я просто отображаю интерактивную форму без сплющивания), он работает нормально, даже в OSGi. Этот сценарий, однако, не использует рабочую флягу XFA.
Попробуйте 2 - использовать конфигурацию Private-Package для maven-bundle-plugin
Из сообщения об ошибке в Try 1 кажется, что проблема связана с проводкой в комплекте. И тогда я подумал: почему бы просто не вложить все вещи, не относящиеся к OSGi, прямо в мой пакет как частные пакеты?
Поэтому я редактирую плагин maven следующим образом:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven-bundle-plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Bundle-Activator>com.testing.xfa.Activator</Bundle-Activator>
<Export-Package>
com.testing.xfa*;version=${project.version}
</Export-Package>
<Import-Package>
*
</Import-Package>
<Private-Package>com.itextpdf.*</Private-Package>
</instructions>
</configuration>
</plugin>
Теперь, когда я устанавливаю и пытаюсь запустить свой пакет, я получаю следующее (типичное OSGi) сообщение:
Error executing command: Error executing command on bundles:
Error starting bundle 66: Unable to resolve xfa-test [66](R 66.0): missing requirement [xfa-test [66](R 66.0)] osgi.wiring.package; (osgi.wiring.package=org.antlr.v4.runtime) Unresolved requirements: [[xfa-test [66](R 66.0)] osgi.wiring.package; (osgi.wiring.package=org.antlr.v4.runtime)]
Что приводит меня к пробирке с пробой и ошибкой, когда я добавляю в пакет все больше и больше приватных пакетов, пока мои теги Private-Package не будут выглядеть так:
<Private-Package>com.itextpdf.*;org.antlr.*;org.abego.treelayout.*</Private-Package>
На этом этапе я получаю следующую ошибку (и она не исчезает, даже если я добавлю "org.apache.jcp.*" В список частных пакетов).
Error executing command: Error executing command on bundles:
Error starting bundle 69: Unable to resolve xfa-test [69](R 69.0): missing requirement [xfa-test [69](R 69.0)] osgi.wiring.package; (osgi.wiring.package=org.apache.jcp.xml.dsig.internal.dom) Unresolved requirements: [[xfa-test [69](R 69.0)] osgi.wiring.package; (osgi.wiring.package=org.apache.jcp.xml.dsig.internal.dom)]
Попробуйте 3 - Установите все пакеты, которые вызывают проблемы, которые Private-Package не решает.
Это была еще одна кроличья нора проб и ошибок, но мой подход заключался в следующем: - Сохранить все не-osgi банки в моем теге приватных пакетов - Удалить полностью завернутые банки (так как они теперь встроены в мой комплект) - Добавить следующий Karaf пучки, по одному:
bundle:install -s mvn:com.itextpdf/itextpdf/5.5.11
bundle:install -s mvn:com.itextpdf.tool/xmlworker/5.5.11
bundle:install -s mvn:org.apache.directory.studio/org.apache.commons.codec/1.8
bundle:install -s mvn:org.apache.santuario/xmlsec/2.0.2
bundle:install -s mvn:org.bouncycastle/bcprov-jdk15on/1.56
bundle:install -s mvn:org.bouncycastle/bcpkix-jdk15on/1.56
bundle:install -s mvn:org.bouncycastle/bcprov-jdk15/1.45
bundle:install -s wrap:mvn:org.apache.xmlbeans/xmlbeans/2.6.0
В промежутке между добавлением каждого пакета я пытаюсь запустить свой собственный и проверить, какие ошибки я получаю. Вымойте, промойте, повторите. Через час или два у меня есть тег Private Packahe, который выглядит следующим образом:
<Private-Package>com.itextpdf.*;org.antlr.*;org.abego.treelayout.*;org.bouncycastle.*;org.mozilla.*</Private-Package>
На этом этапе Karaf больше не генерирует исключения проводки osgi, но дает мне следующее NullPointerException
karaf@root()> start 87
Starting the bundle
Rendering PDF
java.lang.NullPointerException
at com.itextpdf.tool.xml.xtra.xfa.positioner.Positioner.<init>(Positioner.java:190)
at com.itextpdf.tool.xml.xtra.xfa.positioner.SubFormPositioner.<init>(SubFormPositioner.java:50)
at com.itextpdf.tool.xml.xtra.xfa.pipe.FormBuilder.buildSubForm(FormBuilder.java:215)
at com.itextpdf.tool.xml.xtra.xfa.pipe.FormBuilder.buildSubForm(FormBuilder.java:152)
at com.itextpdf.tool.xml.xtra.xfa.pipe.FormBuilder.getFormDom(FormBuilder.java:566)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.flatten(XFAFlattener.java:901)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.flatten(XFAFlattener.java:491)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.flatten(XFAFlattener.java:359)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.flatten(XFAFlattener.java:329)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.flatten(XFAFlattener.java:300)
at com.testing.xfa.Renderer.flattenXfa(Renderer.java:124)
at com.testing.xfa.Renderer.renderDoc(Renderer.java:52)
at com.testing.xfa.Activator.start(Activator.java:35)
at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:697)
at org.apache.felix.framework.Felix.activateBundle(Felix.java:2226)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2144)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998)
at org.apache.karaf.bundle.command.Start.executeOnBundle(Start.java:38)
at org.apache.karaf.bundle.command.BundlesCommand.doExecute(BundlesCommand.java:64)
at org.apache.karaf.bundle.command.BundlesCommand.execute(BundlesCommand.java:54)
at org.apache.karaf.shell.impl.action.command.ActionCommand.execute(ActionCommand.java:83)
at org.apache.karaf.shell.impl.console.osgi.secured.SecuredCommand.execute(SecuredCommand.java:67)
at org.apache.karaf.shell.impl.console.osgi.secured.SecuredCommand.execute(SecuredCommand.java:87)
at org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:480)
at org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:406)
at org.apache.felix.gogo.runtime.Pipe.run(Pipe.java:108)
at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:182)
at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:119)
at org.apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.java:94)
at org.apache.karaf.shell.impl.console.ConsoleSessionImpl.run(ConsoleSessionImpl.java:274)
at java.lang.Thread.run(Thread.java:745)
Error executing command: Error executing command on bundles:
Error starting bundle 87: Activator start error in bundle xfa-test [87].
В этот момент я считаю, что я делаю что-то ОЧЕНЬ НЕПРАВИЛЬНО, поэтому я надеюсь получить некоторую помощь здесь, в SO.
Любые указатели будут оценены