Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependency chaos with Apache POI #72

Closed
Nutellaeis opened this issue Jul 24, 2019 · 3 comments
Closed

Dependency chaos with Apache POI #72

Nutellaeis opened this issue Jul 24, 2019 · 3 comments

Comments

@Nutellaeis
Copy link

I am currently trying to use Apache POI, Java Fx and JAXB in the same Project. I tried it step by step, and it seems to break as soon as I add POI.
The Gradlefile currently looks like this.

plugins {
  id 'eclipse'
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.7'
  id 'org.beryx.jlink' version '2.12.0'
  id 'org.openrepose.gradle.plugins.jaxb' version '2.5.0'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'javax.xml.bind:jaxb-api:2.3.1'
    jaxb 'org.glassfish.jaxb:jaxb-xjc:2.3.1'
    implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.1'
    implementation 'org.apache.poi:poi-ooxml:4.1.0'
    implementation 'net.harawata:appdirs:1.0.3'
}

sourceCompatibility = 1.12
targetCompatibility = 1.12

mainClassName = "$moduleName/greatapp.Mainclass"

jaxb {
  xsdDir = "src/main/resources/xml"
}

javafx {
    version = "12"
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

jlink {
    forceMerge 'jaxb'
    imageZip = file("$buildDir/Great App.zip")
    options = ['--bind-services', '--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'Great App'
    }
}

eclipse {
    classpath {
        containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
        file {
            whenMerged {
                entries.findAll { it.properties.kind.equals('lib') && !it.properties.path.contains("junit") }.each {
                    it.entryAttributes['module'] = 'true'
                }
                entries.findAll { it.properties.path.startsWith('org.eclipse.jdt.launching.JRE_CONTAINER') }.each {
                    it.entryAttributes['module'] = 'true'
                }
                entries.find { it.path == 'src/main/java' }.output = 'bin/main'
                entries.forEach { entry ->
					def entryIn = { it.find { file(entry.path).equals(it) } }
					if (entry.kind == 'lib') {
						entry.entryAttributes['test'] =
							entryIn(configurations.testRuntimeClasspath) &&
							!entryIn(configurations.runtimeClasspath)
					}
	            }
            }
        }
    }
}

If I do not use forceMerge 'jaxb' I get a error: module not found: java.xml.bind (Even though I actually have a requires java.xml.bind; in my module-info.java.

If I do use it I get a:


Cannot derive uses clause from service loader invocation in: javax/xml/bind/ServiceLoaderUtil.firstByServiceLoader().
Cannot derive uses clause from service loader invocation in: org/apache/commons/compress/utils/ServiceLoaderIterator.<init>().
error: module not found: java.activation

But if I add implementation 'javax.activation:activation:1.1.1' to the dependencies I get


error: the unnamed module reads package javax.activation from both activation and java.activation
error: module poi reads package javax.activation from both activation and java.activation
error: module activation reads package javax.activation from both activation and java.activation
error: module javafx.controlsEmpty reads package javax.activation from both activation and java.activation
error: module javafx.graphicsEmpty reads package javax.activation from both activation and java.activation
error: module javafx.baseEmpty reads package javax.activation from both activation and java.activation
error: module poi.ooxml.schemas reads package javax.activation from both activation and java.activation
error: module org.apache.commons.compress reads package javax.activation from both activation and java.activation
error: module curvesapi reads package javax.activation from both activation and java.activation
error: module slf4j.api reads package javax.activation from both activation and java.activation
error: module jna.platform reads package javax.activation from both activation and java.activation
error: module org.apache.commons.codec reads package javax.activation from both activation and java.activation
error: module org.apache.commons.collections4 reads package javax.activation from both activation and java.activation
error: module commons.math3 reads package javax.activation from both activation and java.activation
error: module xmlbeans reads package javax.activation from both activation and java.activation
error: module jna reads package javax.activation from both activation and java.activation
error: module poi.ooxml reads package javax.activation from both activation and java.activation
error: module net.harawata.appdirs reads package javax.activation from both activation and java.activation
error: module java.activation reads package javax.activation from both activation and java.activation
error: module java.xml.bind reads package javax.activation from both java.activation and activation

Is it possible to get this to work?

@siordache
Copy link
Member

You probably don't need the javax.activation:activation:1.1.1. Instead, try this:

Step 1

Put this in your jlink block:

    forceMerge 'jaxb', 'istack', 'stax'

This should get rid of the module not found: java.activation error.

Step 2

You will probably get errors such as:

the service implementation type must be a subtype of the service interface type, or have a public static no-args method named "provider" returning the service implementation

or

the service implementation does not have a default constructor

Execute:

./gradlew suggestMergedModuleInfo

It will print something like this:

    mergedModule {
        requires 'java.xml.crypto';
        requires 'java.logging';
        requires 'java.xml';
        requires 'com.sun.xml.txw2';
        requires 'java.desktop';
        requires 'java.datatransfer';
        requires 'java.compiler';
        requires 'java.security.jgss';
        requires 'jdk.javadoc';
        requires 'com.sun.xml.fastinfoset';
        provides 'javax.xml.bind.JAXBContext' with 'com.sun.xml.bind.v2.ContextFactory';
        provides 'org.apache.xmlbeans.impl.store.QueryDelegate.QueryInterface' with 'org.apache.xmlbeans.impl.xquery.saxon.XBeansXQuery';
        provides 'org.apache.xmlbeans.impl.store.PathDelegate.SelectPathInterface' with 'org.apache.xmlbeans.impl.xpath.saxon.XBeansXPath';
    }

Remove the lines contaning provides clauses and put the resulting mergedModule configuration in your jlink block.

Execute ./gradlew jlink.

Step 3

If you still get errors, you may need to do additional adjustments to the mergedModule configuration, for example you may need to add some uses or provides clauses.

@Nutellaeis
Copy link
Author

It works! Thank you. I could never have figured that out myself.

@siordache
Copy link
Member

Great! Time to treat yourself with a Nutella Eis 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants