ASM's Frame class has no generic type - java-bytecode-asm

ASM documentation (pdf) says, that Frame class has generic type, providing an example of usage: Frame<BasicValue>. (at p. 119, if needed)
When looking at the source, we can see it's declaration like Frame<V extends Value>.
But for some reason, when in my project I specify maven dependencies,
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-analysis</artifactId>
<version>4.2</version>
</dependency>
or just load according artifacts manually from repository, attempt to use Frame<...> ends with error:
Type org.objectweb.asm.tree.analysis.Frame doesn't have type parameters
And Intellij IDEA decompiler says Frame really has no ones.
The same issue takes place with Analyzer and Interpreter classes.
How can I beat that?

Complementing an answer of #dejvuth:
asm-debug-all happens to be of Java 5.0 version and contains all generic types. Morever, it's binary compatible with plain asm library with no generics

From ASM FAQ
14. What is the earliest JDK required to use ASM?
...
The asm.util and asm.tree packages require JDK 1.2, ...
and History of ASM 4.0 RC1
generified the API to use generics and varargs. However, almost all jars are still small and 1.2 compatible.
Basically, when jarred, ASM optimizes the bytecode, which (among others) makes it backward-compatible with 1.2 by changing its major version to 46 (see org.objectweb.asm.optimizer.ClassOptimizer).
I guess there are two options available: use it without generics or compile the source by yourself.

Related

Java 14 support in Groovy?

All groovyconsole binary distros I have found don't support Java 14. The console complains if you try to specify a Jar file that has been compiled with Java 14, for example.
The obvious solution, I thought, was to build Groovy with Java 14. That seems non-trivial.
gradle.wrapper.properties files contain
distributionUrl=http://services.gradle.org/distributions/gradle-2.3-bin.zip
which is a broken URL. Change that to https and then it works, partially.
You then get
FAILURE: Build failed with an exception.
What went wrong:
Could not determine java version from '14.0.2'.
Reading the docs for gradle makes it clear that most (all?) versions of gradle do not support Java 14. Definitely version 2.3 does not. Why - I have no idea.
So... back to my original question. How can I get a groovy installation to support Java 14?
Thanks!
If the Jar cannot be loaded, it is most likely the asm lib, which is unable to read it. To read Java14 you need at least ASM 7.2 I think. ASM in Groovy is not provided as standalone library, because of possible conflicts with other jar dependencies it is shadowed (bytecode is transformed by renaming the packages and directly added to the Groovy jar). I see here 2 options:
compile Groovy yourself and change the dependencies to have at least ASM 7.2. It does not matter if you build Groovy with a lower version of the JDK, the JDK still allows to read "old" jars.
use at least Groovy 2.5.9, 3.0.0 or 2.4.19, as they include asm 7.2 or higher
Of course this does not mean it will change the Groovy Gradle is using easily. For that I would use Groovy 2.5 and read Bumping Groovy version in Gradle?
If this does not solve the problem or answer the question I would need more details.

Groovy-Eclipse 2.5.2: java.lang.ClassNotFoundException: picocli.CommandLine$ParameterException

I'm using Eclipse 4.5 with the Groovy-Eclipse 2.9.2/4.5 plugin which I thought was supposed to have the Groovy 2.5 compiler. However, it didn't have any picocli support so I added the groovy-cli-picocli-2.5.2-indy.jar to my classpath and was able to compile. However #2, when trying to run the script via Eclipse I get:
java.lang.ClassNotFoundException: picocli.CommandLine$ParameterException
It looks like groovy-cli-picocli-2.5.2-indy.jar does not have CommandLine class at all.
I would just throw jars at this from the fullblown picocli distribution but I'm under the impression they all have to somehow wrap nicely into Eclipse Groovy library via groovy.cli.picocli.CliBuilder.
Is my Groovy 2.5.2 missing this or am I somehow missing the boat on how it's supposed to work because picocli is not working for me in this configuration. Thanks!
You are correct: groovy-cli-picocli-2.5.2.jar (and groovy-cli-picocli-2.5.2-indy.jar) do not contain the picocli classes.
You need to add the picocli jar to the classpath.
If you use Maven, the groovy-all POM should include all dependencies.
(My original answer mentioned picocli classes that are shaded into the groovy-2.5.x.jar under the groovyjarjarpicocli package but these are intended for use internally by Groovy and not meant to be used by applications.)

JDK 9: JUnit 5 test compile with SpringExtension produces java.lang.NoClassDefFoundError: org/w3c/dom/ls/DocumentLS

I believe this problem not to be related to module exclusions in JDK 9 (as with java.se.ee), but rather with the fact that JDK 9 includes a newer version of org.w3c.dom.ls in the java.xml module that does not have the DocumentLS class.
The important bit of the stack trace is this:
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [spring-test/test-container.xml]; nested exception is java.lang.NoClassDefFoundError: org/w3c/dom/ls/DocumentLS
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:414)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
Even if I include a runtime dependency with this class, like xerces:xerces 2.4.0, the JDK java.xml module is preferred (I guess).
I am using Gradle 4.1. Is there any way to restrict the scope of a
JDK provided module?
As you have correctly analyzed, the package org.w3c.dom.ls is present in the platform module java.xml. Any class on the class path that is in the same package will be ignored. That's called a split package and several fixes exist - the following two might help you.
Patch java.xml
You can add the classes of the Xerxes JAR to the java.xml module with --patch-module:
java --patch-module java.xml=xerxes-4.0.0.jar ...
I've never tried that with a JAR that contains some of the same classes. As I understand it, the JDK classes will then be replaced with the Xerxes classes, which means they better be a fully binary compatible replacement.
Upgrade java.xml
Another hope is to replace java.xml with the upgrade module path:
The upgrade module path (--upgrade-module-path) contains compiled definitions of modules intended to be used in place of upgradeable modules built-in to the environment (compile time and run time).
You face two problems:
the upgrade module path is supposed to be used only for upgradable modules (which java.xml is not), but I think I've read somewhere that that's not enforced (yet?) - didn't try it
the artifact you replace java.xml with needs to be fully binary compatible update - would that be the case for Xerxes?
From what I can tell, DocumentLS is from a 2002 draft of the W3C API, it doesn't appear to have made it into a released version. It looks like xerces-2.4.0 (from 2006?) includes it but newer versions don't. So upgrading to a more recent Xerces may be needed here. If Spring really depends on DocumentLS then it will need to be updated too.

Was OpenSagres allowed to use Apache POI-like packages?

While searching for a free solution to implement a DOC(x)-to-PDF transformation for an internal business application, I stumbled upon the org.apache.poi.xwpf.converter.* packages.
I found some examples e.g.
http://www.programcreek.com/java-api-examples/index.php?api=org.apache.poi.xwpf.converter.pdf.PdfOptions
I saw the packages starting with "org.apache.poi..." so I thought "oh great, OSS". But after further search, I realized that source code isn't coming from Apache, rather from an obscure French company I never heard of, OpenSagres: http://www.opensagres.fr/
For example http://poi.apache.org/apidocs/index.html has nothing about those packages.
I then found the matching Javadoc API: http://oss.opensagres.fr/xdocreport/javadoc/1.0.3/org/apache/poi/xwpf/converter/core/package-summary.html
...as well as source code on GitHub:
https://github.com/opensagres/xdocreport/wiki/XWPFConverterPDFViaIText org.apache.poi.xwpf.converter.pdf provides...
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>
<version>${XDOCREPORT_VERSION}</version>
</dependency>
https://github.com/opensagres/xdocreport/wiki/XWPFConverterXHTML org.apache.poi.xwpf.converter.xhtml provides...
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId>
<version>XDOCREPORT_VERSION</version>
</dependency>
Jars are also available (for download) inside docx.converters-xxx-sample.zip archive file, packaged (under the "libs" folder) as:
org.apache.poi.xwpf.converter.core-1.0.4.jar
org.apache.poi.xwpf.converter.pdf-1.0.4.jar
org.apache.poi.xwpf.converter.xhtml-1.0.4.jar
And when you look at the source code, there is even a copyright for The XDocReport Team e.g. see
https://github.com/opensagres/xdocreport/blob/master/thirdparties-extension/org.apache.poi.xwpf.converter.core/src/main/java/org/apache/poi/xwpf/converter/core/AbstractXWPFConverter.java
Copyright (C) 2011-2015 The XDocReport Team <xdocreport#googlegroups.com>
How is that even possible? I mean, prefixing a package from a well-known entity which releases OSS should be restricted, no?
Moreover, even if not coming from Apache, I can't use this source code/library/whatever, because:
(it) depends on iText 2.1.7 due to licensing issue(s), see: iText 5.5.0 with XDocReport 1.0.4 which should not be used anymore (but can I really trust the commenter... as he's the author of the code??? https://stackoverflow.com/users/1622493/bruno-lowagie )
there's a version with iText 5.x (https://github.com/opensagres/xdocreport/tree/master/thirdparties-extension/org.apache.poi.xwpf.converter.pdf.itext5) but it's not free! see http://itextpdf.com/Pricing
So how am I supposed to do?

May I use jxls and apache poi together?

I'm making an application to analize some data and the result must be presented in excel files. In that sense I started to use Apache POI (3.11). Due to some reports consumes a lot of time and memory to be reproduce, I made an investigation and I found jxls, after some test I thought was the solution. But now I found a problem: can´t work both frameworks together.
I have to update Apache POI from 3.11 to 3.14, in order to work with jxls-2.3.0
I made an extra package in order to make my tests with jxls, not problem
I try to migrated one of my classes from Apache POI to jxls, and a I got this error: java.lang.IllegalStateException: Cannot load XLS transformer. Please make sure a Transformer implementation is in classpath. This is the code of my method:
private void prepareNewReport(File excelFile) {
List perforaciones = makePerforacionReport
.makePerforacionData(escenario);
try (InputStream is = ReportePerforacionTotalDialog.class
.getResourceAsStream("PerforacionTotal_template.xls")){
try (OutputStream os = new FileOutputStream(excelFile)) {
Context context = new Context();
context.putVar("perforaciones", perforaciones);
JxlsHelper.getInstance().processTemplate(is, os, context);
LOGGER.logger.log(Level.INFO, "Archivo de perfortacion generado con éxito");
}
} catch (IOException e) {
LOGGER.logger.log(Level.SEVERE, "Problemas buscando el archivo", e);
}
}
How could be this possible?. In the same project I have my test class, just another package and its working fine. As you can see it´s not so much different from the example in the jxls page and the imports are the same.
But even worst, when I tried to make clean & build of my project, then I got this other error:
java.lang.RuntimeException: com.sun.tools.javac.code.Symbol$CompletionFailure: class file for org.openxmlformats.schemas.officeDocument.x2006.docPropsVTypes.CTArray not found
I looked at every library that I importede in order to work with jxls and apache poi, and that´s rigth, that class is not there. Just to see if there a conflict among these two framewoks, I eliminated from the class path all libraries needed to use jxls. Clean & build again, and not problem, I have my .jar file to send to my customer, but incomplete.
I could try to replace all classes that use Apache POI, but that means a lot of work, since POI is used in my project to read excel files with data many times and to write another many files to excel. I planned to use jxls in order to take advantage of use templates.
I will apreciate any help or suggestion.
For the first error, it would appear that the JXLS transformer for Apache POI is missing in your classpath when running the application. Check the JXLS getting started info here: http://jxls.sourceforge.net/getting_started.html
As it is explained in Transformers section (see Main Concepts)) Jxls core module does not depend on any specific Java-Excel library and works with Excel exclusively through a predefined interface. Currently Jxls supplies two implementations of this interface in separate modules based on the well-known Apache POI and Java Excel API libraries.
If you're using maven, be sure to include in your pom.xml the jxls-poi dependency listed on the JXLS getting started page:
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls-poi</artifactId>
<version>1.0.9</version>
</dependency>
For the second issue, org.openxmlformats.schemas.officeDocument.x2006.docPropsVTypes.CTArray is not in the apache POI ooxml schemas jar files for either 3.11 (poi-ooxml-schemas-3.11-20141221.jar) or 3.14 (poi-ooxml-schemas-3.14-20160307.jar). POI uses a stripped down set of ooxml schema classes, you will need to get the ooxml schemas complete jar from http://central.maven.org/maven2/org/apache/poi/ooxml-schemas/1.3/ or if you're using maven (or another build tool), get the dependency for your build from https://mvnrepository.com/artifact/org.apache.poi/ooxml-schemas/1.3
e.g for maven:
<!-- https://mvnrepository.com/artifact/org.apache.poi/ooxml-schemas -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.3</version>
</dependency>
Be sure to remove the poi-ooxml-schemas dependency from your maven pom.xml so that ooxml-schemas above takes precedence instead.

Resources