We are developing a fairly large project and have many dependencies. Recently, we ran into an issue with a conflict between two of them, agileAPI.jar and axis.jar. Both are 3rd party libraries.
The code in question depends directly on agileAPI.jar. If I build it with just that in the build path, everything that depends on it works correctly.
As soon as I add axis.jar to the build path (just adding it, not writing code that depends on it), everything goes wrong. Some of the code that depended on the first library is now throwing exceptions from the 2nd library. It is as if the first library is picking and choosing methods to call from the 2nd library, instead of whereever it was calling them from prior.
I have code in the project that needs axis.jar directly, so I can't just remove it from the build path. I need to find a way to have these two exist in the same build path, but ignore each other.
It should be noted that both libraries coexisted prior to a recent upgrade with agile. I have been working with Oracle's support team to try and resolve this. After two weeks, though, I am looking for other sources of help.
Our environment is Windows and Eclipse, although in testing this, it also occurs when running java from a command line. Our JDK is 1.5.0_22.
Any help would be appreciated.
Thank you,
David
EDIT:
As requested, here are the stack traces that we see. The first stack trace is printed in the code beyond my control:
java.lang.NoSuchMethodError: org.apache.axis.description.OperationDesc.setStyle(Lorg/apache/axis/constants/Style;)V
at com.agile.webfs.components.fileserver.client.FileServerSoapBindingStub._initOperationDesc1(FileServerSoapBindingStub.java:37)
at com.agile.webfs.components.fileserver.client.FileServerSoapBindingStub.<clinit>(FileServerSoapBindingStub.java:20)
at com.agile.webfs.components.fileserver.client.FileServerWSServiceLocator.getFileServer(FileServerWSServiceLocator.java:43)
at com.agile.webfs.client.IFSLocator.getRemoteFileServer(IFSLocator.java:128)
at com.agile.webfs.client.IFSLocator.getConnection(IFSLocator.java:101)
at com.agile.api.pc.EJBLookup.createFileSession(EJBLookup.java:444)
at com.agile.api.pc.EJBLookup.getFileSession(EJBLookup.java:432)
at com.agile.api.pc.attachment.IFSOutputStream.getFileSession(IFSOutputStream.java:133)
at com.agile.api.pc.attachment.IFSOutputStream.copyFrom(IFSOutputStream.java:87)
at com.agile.api.pc.attachment.IFSOutputStream.copyFrom(IFSOutputStream.java:115)
at com.agile.api.pc.TableAttachment.uploadFile(TableAttachment.java:886)
at com.agile.api.pc.TableAttachment$AddFiles2Action.doSdkAction(TableAttachment.java:724)
at com.agile.api.common.SDKAction.run(SDKAction.java:23)
at com.agile.api.common.OracleAuthenticator.doAs(OracleAuthenticator.java:131)
at com.agile.api.common.Security.doAs(Security.java:54)
at com.agile.api.common.Security.doAs(Security.java:109)
at com.agile.api.pc.TableAttachment.addFiles2(TableAttachment.java:483)
at com.agile.api.pc.TableAttachment.createNewBlob2(TableAttachment.java:459)
at com.agile.api.pc.TableAttachment.doCreateServerRowWithParam(TableAttachment.java:363)
at com.agile.api.pc.Table.createTableRow(Table.java:238)
at com.agile.api.pc.TableAttachment.createTableRow(TableAttachment.java:169)
at com.agile.api.pc.Table.createRow(Table.java:202)
at com.[snip].updateAttachments(VaultImportService.java:3068)
at com.[snip].processIncorporatedFile(VaultImportService.java:926)
at com.[snip].processPdxFile(VaultImportService.java:532)
at com.[snip].processPdxRequest(VaultImportService.java:388)
at com.[snip].<init>(VaultImportService.java:299)
at com.[snip].main(VaultImportService.java:3660)
After the exception bubbles up and we catch it, the stacktrace that we print looks like:
at com.agile.api.pc.Session.createError(Session.java:1772)
at com.agile.api.pc.EJBLookup.createFileSession(EJBLookup.java:454)
at com.agile.api.pc.EJBLookup.getFileSession(EJBLookup.java:432)
at com.agile.api.pc.attachment.IFSOutputStream.getFileSession(IFSOutputStream.java:133)
at com.agile.api.pc.attachment.IFSOutputStream.copyFrom(IFSOutputStream.java:87)
at com.agile.api.pc.attachment.IFSOutputStream.copyFrom(IFSOutputStream.java:115)
at com.agile.api.pc.TableAttachment.uploadFile(TableAttachment.java:886)
at com.agile.api.pc.TableAttachment$AddFiles2Action.doSdkAction(TableAttachment.java:724)
at com.agile.api.common.SDKAction.run(SDKAction.java:23)
at com.agile.api.common.OracleAuthenticator.doAs(OracleAuthenticator.java:131)
at com.agile.api.common.Security.doAs(Security.java:54)
at com.agile.api.common.Security.doAs(Security.java:109)
at com.agile.api.pc.TableAttachment.addFiles2(TableAttachment.java:483)
at com.agile.api.pc.TableAttachment.createNewBlob2(TableAttachment.java:459)
at com.agile.api.pc.TableAttachment.doCreateServerRowWithParam(TableAttachment.java:363)
at com.agile.api.pc.Table.createTableRow(Table.java:238)
at com.agile.api.pc.TableAttachment.createTableRow(TableAttachment.java:169)
at com.agile.api.pc.Table.createRow(Table.java:202)
at com.[snip].updateAttachments(VaultImportService.java:3068)
at com.[snip].processIncorporatedFile(VaultImportService.java:926)
at com.[snip].processPdxFile(VaultImportService.java:532)
at com.[snip].processPdxRequest(VaultImportService.java:388)
at com.[snip].<init>(VaultImportService.java:299)
at com.[snip].main(VaultImportService.java:3660)
In both cases, the line "at com.agile.api.pc.Table.createRow(Table.java:202)" is the agileAPI call that I am making. I have removed our package structure, as it identifies the company that I work for. They value privacy and security.
I'd advise you to check these two things first:
Open the axis.jar file with some zip utility, like 7-Zip or WinRar. See if there's a folder called "services" in the META-INF folder in the jar. If there is, it's possible that the axis.jar file specifies implementations for specific interfaces that somehow don't interoperate with agileAPI. Also do the same for agileAPI.jar, since it might itself declare an interface implementation that axis doesn't like.
Open both agileAPI.jar and axis.jar with a zip utility, then check if there's packages with the same name. If there's none, it won't be a naming conflict. If there's one or more, open the corresponding folders and do the same check recursively. If you end up with at least one class with the same name in the same package across the two jars, it's probably a naming conflict.
That should catch the most obvious issues. If none of this is the case, we'll need to look deeper.
A way to solve such classpath issues is to use a module system such as OSGi or the NetBeans Platform module system where each module has its own classloader.
Related
We have maven apps that until recently were on JDK8. We just upgraded them to JDK11 and are trying to take advantage of the JPMS from JDK9 by making our utility libraries into modules.
We originally had this kind of path:
utils/some-library1/src/main/java/com/company/team/utils/lib1/Util1.java
There, java is the "source root".
So a colleague placed the module-info.java file in the lib1 folder and declared it thus:
module utils.lib1 {
exports com.company.team.utils.lib1;
}
From the command line that builds and works, so he assumes everything is all module-y goodness.
But when I opened in Intellij, it had an ugly red line and the message said I should move it to source root. It then moved it to the "java" folder above. Fair enough.
That caused me to dig around trying to find out more about this JPMS that my colleague had implemented. After a lot of searching and experiments, I also determined that the "java" folder, as "source root", should be renamed to the name of the module ("utils.lib1"). So now I have these two files:
utils/some-library1/src/main/utils.lib1/module-info.java
utils/some-library1/src/main/utils.lib1/com/company/team/utils/lib1/Util1.java
And even Intellij is happy. Hooray! So I refactor all the other libraries. Suddenly I hit a major snag in let's call it lib2 with this line:
module utils.lib2 {
exports com.company.team.utils.lib2;
requires java.ws.rs;
}
Intellij flags the module with the red error squiggle again, this time saying:
Module 'utils.lib2' reads package 'javax.activation' from both 'jakarta.activation' and 'jakarta.activation'
I did some digging and found out the following:
java.ws.rs pulls in one of the following (it depends on which app):
javax.ws.rs-api-2.1.1.jar
jakarta.ws.rs-api-2.1.6.jar
Their module-info.java files contain this line:
requires transitive java.xml.bind;
Which pulls in one of:
jakarta.xml.bind-api-2.3.2.jar
jakarta.xml.bind-api-2.3.3.jar
jaxb-api-2.4.0-b180830.0359.jar
Which all have this line:
requires transitive jakarta.activation;
And that's where I give up. Our libraries are big hefty things that are hard to parse completely, so to simplify I created a maven app with just one class and all it does is import javax.ws.rs.core.Link.
And IntelliJ still gives that crazy error that I can't figure out and Google has been adamant in refusing to tell me.
Is it really broken or is Intellij just as confused as I?
I gave the long story both to show what we've done and to let you know that I'm very new to modules. So if it's a simple thing, please excuse me. I am just stumped though.
Additionally, are there any obvious tests one can perform at the command line to validate module configuration?
I've had inconsistent luck with jdeps, javac, and actually running as indicators of problems.
My suspicion is that things only work now because they're all in the unnamed module. But I need to get everything working if I'm going to convince anyone to change it.
EDIT
This question was reported as already answered, but that is incorrect. The suggested link deals with two different packages (A & B) importing package X. But in my case, the error is that the same package (A & A) imports package X. And this is done a few transitives down, so I have no control over the imports and can't see how to do an exclusion. Also, this problem can be repeated with just single requires statement in module-info.java!
Plus, there is a second question here that is also important that has not been addressed: how to validate the module configuration from command line (without involving the IDE at all).
I also determined that the "java" folder, as "source root", should be renamed to the name of the module
No, it should not. The java source root should be left as is but you must create a package name corresponding to your module name, so it should be /src/main/java/ - source root and then utils/lib1 directory - whidh would be the package.
I came across exact same warning in Intellij and it was genuine. In my case the collision was coming from three separate dependencies using same module name (i.e. 'jakarta.activation'):
'jakarta.activation:jakarta.activation-api:1.2.2'
'javax.activation:javax.activation-api:1.2.0'
'com.sun.activation:jakarta.activation:1.2.2'
It got it resolved for my project by applying explicit exclusions on dependencies which were pulling the last two.
I have a Scala Akka Application which connects to HBase (currently CDP earlier HDP) deployed on rancher; Never faced any trouble when connecting to HDP hbase; Since recent HDP to CDP change, with the same image we are getting no method found on one of the dependency's class in one of the container, where as another container of same image connects to hbase properly.; even though the jar exists in the same image and classpath also.
one of the noticeable difference is change in the order of classpath.
Does change in the classpath order will effect the jars availability.
Does java libraries/classes would load in different order when they would hit a faster CPU cycle at startup.
What could be the reason for such "no class method found".
It certainly can, if the same class file is present in different classpath entries. For example, if your classpath is: java -cp a.jar:b.jar com.foo.App, and:
a.jar:
pkg/SomeClass.class
b.jar:
pkg/SomeClass.class
Then this can happen - usually because one of the jars on your classpath is an older version than the other, or the same but more complicated: one of the jars of your classpath contains a whole heap of different libraries all squished together and one of those components is an older version.
There are some basic hygiene rules to observe:
Don't squish jars together. If you have 500 deps, put 500 entries on your classpath. We have tools to manage this stuff, use them. Don't make striped jars, uber jars, etc.
Use dependency trackers to check if there are version difference in your dependency chain. If your app depends on, say, 'hibernate' and 'jersey', and they both depend on google's guava libraries, but hibernate imports v26 and jersey imports v29, that's problematic. Be aware of it and ensure that you explicitly decide which version ends up making it. Presumably, you'd want to explicitly pick v29 and perhaps check that hibernate also runs on v29*. If it doesn't, you have bigger problems. They are fixable (with modular classloaders), but not easily.
*) Neither hibernate nor jersey actually depend on guava, I'm just using them as hypothetical examples.
For example, if you use maven, check out the enforcer plugin. (groupId: org.apache.maven.plugins, artifactId: maven-enforcer-plugin).
My bet is that there is another version of the jar somewhere in CDP, and occasionally it is loaded before the version that you ship with your project, causing the error.
So, when your container starts, try logging from which location the conflicting class is loaded. This question might help you: Determine which JAR file a class is from
I am currently writing a JavaFX application contained within 1 module and I want to use Javadoc to document all of my code. However, I am noticing that I can't seem to generate Javadocs for packages that have not been exported out of the module in module-info.java. On one hand, that makes sense. Non-exported packages aren't part of the public API. On the other hand, I feel like surely there should be options to enable documentation of internal APIs hidden in non-exported packages, but I've had no success in enabling them.
As this is a Maven project, I've tried the following options with the maven-javadoc-plugin:
<show>private</show>
<additionalOptions>-private</additionalOptions>
<additionalOptions>--show-module-contents all --show-packages all --show-types private</additionalOptions>
None of these work (and I am pretty sure 1 and 2 are the exact same thing). They only show a bit more info on one package that i've exported to another specific module. If I don't have these options, the Modules section of the Javadoc is completely blank with the exception of the module name.
I've done lots of Googling and no one on the Internet seems to bring this issue up. Maybe my Google-Fu is just off? I feel like there's just some silly undocumented flag that I haven't found yet because it can't be the case that you have to export the packages to get Javadocs for them, right?
My project consists of only one module containing 8 packages. None of them need to be fully exported out yet. Only one package containing my JavaFX files needs to be exported to javafx.graphics and that's the only one that gets picked up by Javadoc when I enable <show>private</show>.
Here is a gist of my module and Maven config, if anybody needs it:
https://gist.github.com/urbenlegend/753de7bec598fd07d6b5c0b0ef02d1d0
I am invoking Javadoc generation via mvn compile javadoc:javadoc
Anyone here have any tips? Thanks in advance!
While setting up a project as a template for Slick2d based projects following the instructions here:Slick2d wiki using the provided code for testing setup here at run-time I keep getting a giant block of sealing errors. My thought is that this problem stems from the version of ljgwl.jar in both libraries, however Slick requires both in order to function properly. How can I resolve this?
Package sealing is a Java feature implemented in part in the JAR file format. It is discussed in several places, including in Oracle's Java Tutorial, but the bottom line is that when package sealing is enabled in a Jar's manifest, no classes belonging to that package can appear in any other JAR file.
My thought is that this problem stems from the version of ljgwl.jar in both libraries, however Slick requires both in order to function properly.
I'm not sure what you mean by "library", as that is not a Java concept. I suspect, however, that you're trying to say that you somehow have ljgwl.jar files from two separate sources, and you've put both into your project classpath. That would indeed be a problem, and more than just for package sealing. You can, in fact, be thankful for the sealing errors, for they may have saved you from subtler, more difficult to diagnose runtime errors.
How can I resolve this?
You should have only one copy of LWJGL in your classpath, regardless of any requirements enforced by package sealing, and regardless of how the classes are packaged in jar files. It looks like the Slick2D distribution may come with a copy of LWJGL -- in that case, it's probably wisest to use that one. As long as it's in your classpath (as it must be anyway for Slick2D to use it), any class anywhere in your application can use it.
It gets tricky if you need to contend with a inconsistent requirements for LWJGL version, or if you have obtained a JAR that incorporates the LWJGL classes along with something else, but that doesn't change the bottom line: you must choose one version of LWJGL, use that version exclusively within your application, and include only one copy of it in your classpath.
I had to include some bittorrent java library to my Android project. My workspace: Android Studio 1.0.2 (osx) and jdk8. I've connected its maven-repository (ttorrent:1.4) with Gradle and after starting using main classes and features i've got an error:
java.lang.NoSuchMethodError: No static method encodeHex([BZ)[C in class Lorg/apache/commons/codec/binary/Hex; or its super classes (declaration of 'org.apache.commons.codec.binary.Hex' appears in /system/framework/ext.jar).
I went to library's code and find out that it's using org.apache.commons.codec from where ttorrent is importing encodeHex and calling it. Looks like binaryHex method is gone! Or it never been. But I went to commons.codec's code and found binaryHex in its place and with arguments that I was looking for. How come? Why? My Android Studio found it. But java runtime not.
In fact, the decision was more difficult than I thought. Let's start with the fact that I came across an article by Dieser Beitrag'a, from which it is clear that not one I had similar problems. The whole thing turned out that within the Android operating system already has some libraries that have a higher priority use, rather than loaded with dependencies along with the application. Among them there and my org.apache.commons.codec.
Yes, such things.
To solve the problem in two ways, either you need to pump source code library and using some tool to rename the project (i.e. org.apache.commons.codec to org.apache.commons.codec.android), collected it to a .jar file, include .jar in a project and at code use imports of the necessary classes only "our" library, or just get the required class to your project and do not pull a megabytes of unneeded code. However, I did just that.
Thanks for help!