According to the ASM FAQ, to get example ASM code, I should use the ASMifier class, like this:
java -classpath "asm.jar;asm-util.jar" org.objectweb.asm.util.ASMifier org/domain/package/YourClass.class
But that gets me the error:
Error: Could not find or load main class org.objectweb.asm.util.ASMifier
Looking at JAR files, the ASMifier class seems to be missing, though its helper classes are present:
./org/objectweb/asm/util/ASMifierClassVisitor.class
./org/objectweb/asm/util/ASMifierAnnotationVisitor.class
./org/objectweb/asm/util/ASMifierMethodVisitor.class
./org/objectweb/asm/util/ASMifierAbstractVisitor.class
./org/objectweb/asm/util/ASMifierFieldVisitor.class
This is with ASM 3.3.1, as provided by Fedora 20. Is the FAQ for a newer version, and I should be using different instructions? Did Fedora mess up the packaging (even though their bug-tracker shows nothing)? Something else?
When browsing the SVN repository of ASM, you can read up the revision history of the ASMifier: It was formerly known as the ASMifierClassVisitor which was also this utility's name in version 3.1.1.
ASM never had a reputation of maintaining binary or even compilation compatibility. Thus, you might encounter several problems like the one you describe when using non-bleeding edge versions of the library. (The authors promised to improve this after ASM's version four.) You, or the libraries that you use, should however always repackage ASM into a different namespace in order to avoid such issues. This is even recommended in the FAQ to using ASM.
For running your example, you would have to use:
java -classpath "asm.jar;asm-util.jar" \
org.objectweb.asm.util.ASMifierClassVisitor \
org/domain/package/YourClass.class
Related
I am migrating Java 1.8 to OpenJDK 11. Getting some dependency errors.
"sun.security.x509" is not visible.
BASE64Encoder error
How can I resolve these? I am using Apache Ant for build.
We can't tell you how to address the first problem since you haven't shown us the code where you are using classes in the sun.security.x509 package. A possible workaround might be to use --add-exports and/or --add-opens as described in this blog post:
All You Need To Know For Migrating To Java 11
However, that work-around is liable to stop working in the future. The solution would be to find a way to avoid depending on those classes.
The second problem can be used by rewriting your code to use the java.util.Base64 class (javadoc) that was introduced in Java 8.
I am using Apache Ant for build.
That is not directly relevant. The root cause of the problem is in the code you are building not the build tool you are using.
We have a repository built using Java 8. There are multiple rest services within the repository. We want to migrate to Java 11 and trying to figure out the best way of doing this. We are considering doing module by module. For example changing one service over to Java 11 while the remaining are still Java 8. We are unsure if Maven supports this?
Disclaimer: This is not an answer but just a partial report of my recent experience. Feel free to flag this answer if you feel that it doesn't meet the SO standards.
Does Maven supports this?
Yes, use the compiler plugin 3.8.0/3.8.1
However this migration requires addition care.
Recently we did something like this by migrating from ORACLE JDK 8 to OPENJDK 11. As we have houndreds of repositories with different missions, we faced all kind of problems. Just to cite some that I got here in my e-mail box tagged as [jdk11_migration]:
It is quite obvious but I'd like to highlight that in order to migrate from java 8 to 11 we have to meet the requirements from java 9 and 10 as well
Some maven plugins like cobertura do not support Java 11 and I guess they will never support it. In some cases, these plugins have reached the abandoned life cycle stage. The solution was looking for alternatives in a case to case manner. For example, we replaced cobertura by Jacoco.
rt.jar and tools.jar have been removed! Everything you have explicity refered from them will probably break.
some classes which we shouldn't use in java 9 or less now in java 11 no longer exist. I'm talking about to access classes in packages like sun.*, sun.misc etc. The solution is to look for a one-to-one replacement or refactor the code to avoid the usage.
Reflection usually is the last bullet to use and, for these cases, in java 9 and above we geta warning messages like:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by ...
WARNING: Please consider reporting this to the maintainers of ...
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Although it is not exactly a solution, there is a flag to get rid of this warning --illegal-access=permit . This is particulary important when using surefire maven plugin.
Java 9 introduced the module system then "now" we have the phenomena of clash of packages. For example, messages like "The package org.w3c.dom is accessible from more than one module: , java.xml" . The solution is to find the source of reduntant inclusion (notably duplicated maven dependences or dependences of dependences) and remove it.
Althought it wasn't a problem for us, I just noted that your repository consists in REST components in majority. Probable you will face ClassNotFound issues regarding some packages like javax.xml.bind which were basically dropped out of java standard edition. You can fix it by including they explictly in your pom.xml.
Luckly you may find good questions & anwswers for each issue you will find in your migration here in SO or over internet. There are some migration guides in the wild which are good start points. Specific issues, like obfuscation and IDE integration, can take a little bit of time, but, at least in my experience, this migration was painless than I have supposed.
My suggestion is to upgrade the entire project. Try to have some Java8 and some Java11 modules can be very difficult. As you already know, starting from Java9 module appears. The answer is very generic, so it's difficult to give a detailed response. I suppose:
Your project is managed with maven
You have many artefacts (jar)
You are using some library or framework (who said Spring?)
You are using a Source Version Control (Git or Subversion for example)
You have a multi-module project
The code you wrote works on Java8 and on Java11 platform
My suggested plan:
Create a branch on your SVC for Java11 project's version and start to work on it.
Create a parent module for common definitions
Upgrade maven plugin and all your library to the latest version. For Maven compiler set the Java11 target (the Java11 is supported only by the latest version of Maven Compiler Plugin).
For each module define the exported packages (and specify which packages are required)
If there are many modules, start with only a few of them and then include the remains.
If it can help you, let have a look at this simple project on github (It target Java11 and it's a multi-module Maven project).
Hope it helps.
I am trying to run a map/reduce job and I am getting a java.lang.NoSuchMethodError. I did some research on this and this appears when my code is executed (not compiled). The correct version of the class and methods are there during compilation, but when trying to run, the correct method is not available. The jar file that is causing this is guava. I know this from the stack that is printed. I throws an error when trying to execute the following line of code:
ArrayDeque<Entry<String, String>> a = Queues.newArrayDeque();
This jar is part of the hadoop classpath because it comes with the CDH verson 5.3.0 that I am using. I have tried adding the correct version of guava to the classpath, but the error does not change. My questions are as follows:
I believe that I have correctly identified the issue. Does this seem reasonable to you? I have never come across this error before.
I believe that I need to remove the older version of guava from the classpath and add the new one. However, I really do not know where to begin with correcting this. The command that is issued to hadoop jar does not contain the older version of guava (in the -libjar parm). The jar is part of the hadoop classpath when I issue the command "hadoop classpath". So I am assuming that there is some hadoop config file I could edit to make this go away. Is that the correct way to go, or is there some other thing I need to do?
I am using Java 7, CDH 5.3.0, NetBeans 8.
TIA
At the time that I'm writing this, Hadoop has a dependency on Guava version 11.0.2. It uses the library pretty heavily in its internal implementation.
According to the Guava JavaDocs, the Queues#newArrayDeque method was added in version 12.0. If your code is compiling successfully, then that means that Guava version 12.0 or higher is available on your compilation classpath at build time, but since version 11.0.2 is supplied at runtime by Hadoop, the method doesn't exist, resulting in NoSuchMethodError.
Unfortunately, there is no reliable way to swap out a different Guava version in Hadoop. Specifically, I recommend that you do not attempt to replace the Guava 11.0.2 jar that ships in the Hadoop distro. Replacing this with a different Guava version is untested, and it would risk destabilizing the cluster.
The broader problem is that Hadoop's dependencies "leak" to its clients. HADOOP-11656 is an unimplemented feature request that would isolate Hadoop's internal dependencies away from clients, so that you could more easily use common libraries like Guava at your desired version. Meanwhile, until that feature is implemented, I think your only options are to stick to Guava 11.0.2 APIs, or possibly try inlining some of the Guava code that you really want into your own project directly. The code for Queues#newArrayDeque is visible on GitHub.
public static <E> ArrayDeque<E> newArrayDeque() {
return new ArrayDeque<E>();
}
In this particular case, it looks like it will be easy to replace your code with a direct call to the java.util.ArrayDeque constructor. Thanks to the Java 7 diamond operator, it won't even be much more verbose.
ArrayDeque<Entry<String, String>> a = new java.util.ArrayDeque<>();
There is Java tool (it is called Mallet)
http://mallet.cs.umass.edu/download.php
which I want to use in my .NET project.
To convert this tool to .NET library at first I've tried to build it in single .jar file using Apache Ant. I've done everything corresponding to instructions at link above.
Download Developer Release from Mercurial repository.
Download Apache Ant, install JDK, set JAVA_HOME var to use Apache Ant.
Using Ant I've built single mallet.jar file.
And then I would to convert mallet.jar to .NET library using IKVMC.
When converting, I've got a lot of warnings such as:
Warning IKVMC0108: not a class file "cc/mallet/util/tests/TestPriorityQueue$1.cl
ass", including it as resource
(class format error "51.0")
Despite of these warnings, mallet.dll was created. But when I try to reference to it from my .NET project, it looks "empty". It has not any classes or namespaces. I don't forget to reference to IKVM.OpenJDL.Core.
And this is unusual that I can't find any same problems in Google.
I think that problem is in warnings. And I have never worked with Ant and I don't understand all process exactly.
The class format version 51 was introduced with Java 7.
IKVM most likely doesn't support that version yet and the file name you quote (cc/mallet/util/tests/TestPriorityQueue$1.class) points at an anonymous inner class of TestPriorityQueue that certainly is needed for the library to work correctly.
My suggestion: compile Mallet using an older JDK or at least using the -source and -target switches set to 6 (to ensure that it's compile for Java 6).
FYI v8.1 (currently in RC) of IKVM supports Java 8:
http://weblog.ikvm.net/2015/08/26/IKVMNET81ReleaseCandidate0.aspx
http://sourceforge.net/p/ikvm/mailman/message/34502991/
I found a java code and want to use it in my project. It contains these imports that my JDK does not have :
import com.sun.awt.AWTUtilities;
import com.sun.jna.Native;
import com.sun.jna.platform.WindowUtils;
I referred to sun site and found this download page :
http://www.oracle.com/technetwork/java/javase/downloads/index.html
Is it necessary to download all JDK and JRE and replace it from SUN website? My JDK is version 6 and is up to date.
Thank you all
JNA is an additional library and not part of the standard api, you have to download it (here) and include it in your classpath.
The AWTUtilities class is only distributed with the sun jvm as an implementation detail of the api and as such subject to change, this can break any program depending on it (if possible don't use it).
WindowUtils can be found in the platform.jar, you it can find it on the same page as jna.
Your JDK should have com.sun.awt.AWTUtilities. It is in rt.jar.
Maybe the problem (for that file) is that your IDE excludes the parent the build path ... on the grounds that it is a bad idea to use those classes directly.
The com.sun.jna classes are not in rt.jar. They apparently may be found in a jna.jar, though I haven't yet found a good place to download it from. (If you use Maven, try this.)
You should not use any com.sun packages except as a last resort. These are considered to be implementation details, and they are not part of the JDK API. They can change arbitrarily between versions, so they can cause problems when you try to upgrade JDK versions.
The com.sun classes are almost always wrapped by "official" classes - you should use those instead. You can use these in a last resort situation, but they are already part of the JDK download, so there should be no extra downloading necessary.
EDIT: Looks like you're right, you do need to download some extra jars. The JNA jar is available on maven central (http://mvnrepository.com/artifact/com.sun.jna/jna/3.0.9). Especially if this is a code snippet you found, I would highly advise against using com.sun packages directly.