Outputting Docx4J to PDF File - docx4j

I am using the commercial version of docx4j and we have a requirement to output the document to PDF format. I understand there are two options. One is to use an online converter tool. The other is to use a legacy docx4j-export-fo. We can't use the first approach due to the company firewall rules, so the system needs to be self contained, which means option 2.
My pom looks like the following:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>com.plutext</groupId>
<artifactId>Plutext-Enterprise</artifactId>
<version>8.1.0.4</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-JAXB-Internal</artifactId>
<version>8.2.9</version>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-export-fo</artifactId>
<version>8.2.9</version>
<exclusions>
<exclusion>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>xmlgraphics-commons</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
</exclusion>
</exclusions>
</dependency>
The exclusions were to address the issues detected by the maven enforcer. When attempting to covert the word document to PDF, the test fails with the following:
Looks like your endpoint URL 'http://localhost:9016/v1/00000000-0000-0000-0000-000000000000/convert' is wrong
This seems to indicate the first approach is being used rather than the second, which is not the desired result.
I've also tried using apache poi to do the conversion, but that fails with NPEs. Can anyone suggest how to get round this issue?

The current options are set out at https://www.docx4java.org/blog/2020/09/office-pptxxlsxdocx-to-pdf-to-in-docx4j-8-2-3/
Whether export-fo is used depends on:
Class<?> clazz = Class.forName("org.docx4j.convert.out.fo.FOExporterVisitor");
Can you confirm docx4j-export-fo is on your classpath? Perhaps you have security settings prohibiting reflection?
You can try invoking it directly:
FOSettings settings = Docx4J.createFOSettings();
settings.setOpcPackage(wmlPackage);
settings.setApacheFopMime("application/pdf");
Docx4J.toFO(settings, outputStream, Docx4J.FLAG_NONE);

Related

Spring doesn't see h2 database hence complain about database not available

I'm building a simple reactive web application ( Following Josh long's tech talk ) Simply put I have reactive web, r2dbc and h2 as dependencies.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
So I expect spring would configure everything for me( It does for Josh ). But I get error saying not being able to connect to a database and there is a suggestion asking to include h2(which I already have). What am I doing wrong here?
Description:
Failed to configure a ConnectionFactory: 'url' attribute is not specified and no embedded database could be configured.
Reason: Failed to determine a suitable R2DBC Connection URL
Action:
Consider the following:
If you want an embedded database (H2), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
Ok it was missing r2dbc-h2 dependency. This happened because I didn't add r2dbc when I created the project with start.spring.io then added it and inspect the pom but only copied spring-boot-starter-data-r2dbc.
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-h2</artifactId>
<scope>runtime</scope>
</dependency>
Still bit confusing though. Spring boot says it looks in to the class path and auto configure dependencies but seems like sometimes it need given combination of dependencies.

Unreadable content error after generating word document from template with docx4j

We have recently been using docx4j for a project that requires generating docx from templates with variable injection. To do this, we had purchased the plutext-enterprise libs to be able to merge of multiple documents coupled with variable injection:
<dependency>
<groupId>com.plutext</groupId>
<artifactId>Plutext-Enterprise</artifactId>
<version>6.1.0.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>6.0.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</exclusion>
</exclusions>
</dependency>
The issue is that when the generated document is opened, an error showing "unreadable content" is displayed and asks if we would like to repair the document. Ultimately, I would like to remove this. I've tried a number of things such as upgrading the version of docx4j, but I've kept within the compatibility matrix outlined when using the enterprise libraries.
In addition, I've tried running a test with a completely blank template document to eliminate anything wrong with the content in the doc and the generated document still shows this error. This leads me to believe this is an issue with the library itself. Can anyone advise further on this?
The issue will be that Microsoft has introduced new namespaces prefixes which need to be declared. The solution is to upgrade docx4j to v8.2.9: https://www.docx4java.org/forums/announces/docx4j-8-2-9-released-following-word-updates-t2979.html
Your existing Enterprise jar should be ok with that, but more recent versions are available so upgrading is an option.

Exclude org.codehouse.jackson.* from my War on Wildfly 8.2.0 to use com.fasterxml.jackson.*

I try to use the com.fasterxml.jackson for my JSON Deserialization and Serialization. I put the dependencies for the com.fasterxml version in the pom.xml of my war-project and also added the org.jboss.resteasy.resteasy-jackson2-provider dependency there. However my WildFly throws the exception that it can not find the class org.codehouse.jackson.jaxrs.JacksonJsonProvider. I also tried excluding the resteasy-jackson-provider in my jboss-deployment-structure.xml and added the new resteasy-jackson2-provider as dependency with the service-attribute set to "import" as i found on some previous questions. None of this resolved my problem. The important files (hope i did not miss one):
Jboss-deployment-structure:
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.jboss.resteasy.resteasy-jackson-provider"/>
<module name="org.jboss.resteasy.resteasy-json-provider"/>
</exclusions>
<dependencies>
<module name="org.jboss.resteasy.resteasy-jackson2-provider" services="import"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
Dependencies from pom.xml:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>3.0.10.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.4.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1</version>
<scope>provided</scope>
</dependency>
EDIT: I noticed that there are several duplicate jars in my war (including the resteasy-jackson-provider). To fix this i tried to exclude as much general poms (for example wildfly-parent) from my poms as possible. I now have only the directly necessary dependencies in my poms and the issue still stands (multiple jars i did not include or include with the scope provided in my war). Does anybody have an idea why this might occure?
EDIT 2: Issue is fixed there was a problem with my maven script, which did not clean the war... stupid mistake by my part
I faced the same problem too
Im' not really sure about it but when i tryed i found out that Wildfly has packaged all his module under javaee.api so you couldn't exclude any module or have to exclude all. You have to upgrade your Wildfly version and upgrade package.
I can tell you at least than in the most recent version they use fasterxml. So if you don't need a specific version of fasterXML's jackson, just upgrade wildfly.
For anyone who arrives here I would like to comment that, for me, the key has been this exclusions, expecially important the second one:
<exclusions>
<module name="org.jboss.resteasy.resteasy-jackson-provider"/>
<module name="org.jboss.resteasy.resteasy-json-binding-provider"/>
</exclusions>
So, I hope this can be helpfull for somebody.

Maven dependency exclusions: Same artifact-id issue

I have an Apache Cocoon Project and I wanted to update Apache FOP from 1.0 to 1.1, in order to fix foreign (non-latin) script issues, such as Greek.
I found FOP 1.1 has a Maven dependency:
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>1.1</version>
</dependency>
ERROR: Failed to execute goal on project X: Could not resolve dependencies for project com.X:jar:1.0-SNAPSHOT: Failure to find org.apache.avalon.framework:avalon-framework-api:jar:4.2.0 in http://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced -> [Help 1]
I search for a solution in this issue and I found that this dependency has broken links to some other dependencies, which FOP 1.1 needs to call. These are connected with Avalon framework API 4.2. I read in a mailing list that maybe trying to use exclusions and call extra dependencies is working fine. The solution was this code:
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>1.1</version>
<exclusions>
<exclusion>
<artifactId>avalon-framework-api</artifactId>
<groupId>org.apache.avalon.framework</groupId>
</exclusion>
<exclusion>
<artifactId>avalon-framework-impl</artifactId>
<groupId>org.apache.avalon.framework</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- these two are to correct issues in fop dependency -->
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework-api</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework-impl</artifactId>
<version>4.2.0</version>
</dependency>
Now compilation returns the following ERROR2: "Failed to execute goal org.apache.cocoon:cocoon-maven-plugin:1.0.0-M2:prepare (prepare) on project X: There are at least two artifacts with the ID 'avalon-framework-api': avalon-framework:avalon-framework-api:jar:4.2.0:compile".
Of course there are. Two dependencies are excluded, the broken ones, and two of them are called, the correct ones. How can I fix this issue?
Haven't tested this yet, but perhaps excluding org.apache.avalon.framework v4.2.0 and include the latest v4.3.1 instead. Such as:
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>1.1</version>
<exclusions>
<exclusion>
<groupId>org.apache.avalon.framework</groupId>
<artifactId>avalon-framework-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.avalon.framework</groupId>
<artifactId>avalon-framework-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.avalon.framework</groupId>
<artifactId>avalon-framework-api</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.avalon.framework</groupId>
<artifactId>avalon-framework-impl</artifactId>
<version>4.3.1</version>
</dependency>

Can anyone give a good example of using org.apache.maven.cli.MavenCli programmatically?

I'm trying to create an intelliJ plugin that needs to execute maven targets on the current project. All the talk in the intertubes recommends using the MavenEmbedder. Good luck with that. The 2.0.4 version isn't well supported and there are no references for how to use it.
I gave it a whirl and ran into a wall where the embedder had not been initialized with all the fields it needs. Reflective private member injection? Awesome! Why would anyone need an obvious way to initialize an object?
It seems a few people are using a 2.1 version with some success. I have been unable to find that in a jar or even sources.
I went and checked out the 3.0 version of the embedder project: http://maven.apache.org/ref/3.0-beta-3/maven-embedder/ It does away with the MavenEmbedder object all together and seems to only support access through the main or doMain methods on MavenCli. Has anyone used these methods and can give some advice?
Yeah, the's not much in the way of documentation of MavenCli. The API is significatly simpler but i'd still like some examples. Here's one that works...
MavenCli cli = new MavenCli();
int result = cli.doMain(new String[]{"compile"},
"/home/aioffe/workspace/MiscMaven",
System.out, System.out);
System.out.println("result: " + result);
It takes a dir and runs the 'compile' phase...
Working maven configuration for maven 3.6.3
Code
MavenCli cli = new MavenCli();
System.setProperty("maven.multiModuleProjectDirectory", workingDirectory);
cli.doMain(new String[]{"compile"}, workingDirectory, System.out, System.err);
Dependencies
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.6.3</version>
</dependency>
<!-- https://issues.apache.org/jira/browse/MNG-5995 -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>3.6.3</version>
</dependency>
<!-- enable logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
</dependency>
</dependencies>
The dependency matrix information for provided scopes and dynamically acquired components can be a bit confusing. It was for me, since it appeared to me that I got all the required items by direct or transitive dependency, but then remote resolution didn't work.
I wanted to jump to Maven 3.3.3 (latest as of 2015-05-25). I got it working without the sisu errors that presented when I tried to optimistically update to current versions of things specified here (and elsewhere). This is a project with a tag that worked with the example specified as of today using JDK8.
https://github.com/mykelalvis/test-maven-embedder/tree/20150525-working
Relevant deps (SLF4J is just so I can see the logs)
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-connector-basic</artifactId>
<version>1.0.2.v20150114</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-wagon</artifactId>
<version>1.0.2.v20150114</version>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-http</artifactId>
<version>2.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-provider-api</artifactId>
<version>2.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-http-lightweight</artifactId>
<version>2.9</version>
</dependency>
Running this is:
rm -r ~/.m2/repository/org/apache/maven/plugins/maven-clean-plugin/
mvn exec:java
Probably should have made it a unit test of some sort.
If someone has a superior solution for embedded Maven 3.3.3 (i.e. came up with a smaller or more range-oriented set of required dependencies), please post them.
to build on the comment from #StevePerkins, and using maven version 3.1.0,
I had to exclude the transitive dependency from aether-connector-wagon to wagon-provider-api to get it working.
pom.xml:
(...)
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-connector-wagon</artifactId>
<version>0.9.0.M2</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-provider-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-http</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>
(...)
and here is a java example:
(...)
MavenCli cli = new MavenCli();
ByteArrayOutputStream baosOut = new ByteArrayOutputStream();
ByteArrayOutputStream baosErr = new ByteArrayOutputStream();
PrintStream out = new PrintStream(baosOut, true);
PrintStream err = new PrintStream(baosErr, true);
cli.doMain( new String[] { "clean" }, new File("."), out, err );
String stdout = baosOut.toString("UTF-8");
String stderr = baosErr.toString("UTF-8");
(...)
full example here
There is a dependency matrix for each version of maven-embedder, e.g. for 3.2.5: http://maven.apache.org/ref/3.2.5/maven-embedder/dependencies.html
Based on that I had to use org.apache.maven:maven-embedder:jar:3.2.5, org.apache.maven:maven-aether-provider:jar:3.2.5, and org.apache.maven.wagon:wagon-provider-api:jar:2.8.
It also fixes dependency on very old Guava library, since this version uses 18.0.
Dependency list for Maven Embedded 3.6.3 version that works in my Spring Boot 2.3 project (JDK8 or JDK 11 runtime):
<!-- Maven Embedder -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>3.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-http</artifactId>
<version>3.3.4</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-connector-basic</artifactId>
<version>1.1.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-wagon</artifactId>
<version>1.1.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.usefultoys</groupId>
<artifactId>slf4j-toys</artifactId>
<version>1.6.3</version>
</dependency>
The Maven CLI command looks like to:
// Maven CLI to execute Maven Commands
MavenCli cli = new MavenCli();
int result = cli.doMain(args, workingDirectory,
org.usefultoys.slf4j.LoggerFactory.getInfoPrintStream(LOGGER),
org.usefultoys.slf4j.LoggerFactory.getErrorPrintStream(LOGGER));
HTH