Spring, Jersey, CGLIB and Javassist - java

I am migrating an old project from Ant to Gradle (yes, there is still an Ant-based project in 2014). It has all sorts of nonsense thrown into its lib/ dir, and I'm very keen on dumping anything unnecessary as part of this migration.
The project is based on Spring 3.0.5 and Jersey 1.8. It is not using Hibernate but instead using Cassandra. The project seems to think it needs javassist 3.12.0, but didn't pull cglib.
I thought I had some vague recollection of perhaps one of these optionally using javassist, but it seems by recollection is lying to me. Is it safe to remove this dependency?

Depending on how you're using Spring you might need to add an explicit dependency on CGLIB. It's marked as an optional dependency in 3.0. In Spring 3.2, the CGLIB classes were repackaged into the Spring JARs so an explicit dependency on CGLIB is no longer required. You would need CGLIB if you're proxy-target-class="true" or #Configuration.
I just checked one of my projects that's similar to yours (Spring 3.0.x and Jersey 1.x). I have dependency on Javassist but Maven tells me it's because of Hibernate. I don't see an explicit dependency from Jersey 1.x to Javassist.
If I were you, I'd leave the Javassist dependency out of the POM and let Maven take care of pulling it in if it's necessary. I would only add an explicit dependency on Javassist if it was an optional dependency that I needed or if Maven made the wrong choice about which version to include.
Is it safe to remove this dependency?
It's hard to say without seeing your entire pom.xml or the list of JARs that the Ant script worked with.

Related

Maven different package name in newer dependency

The project I am working on produces a jar that I deploy on azure so Spark runs the job.
It is using an internal dependency A which uses the dependency org.apache.commons:commons-configuration:1.10 yet when I deploy on azure it uses 2.1.1 version by default.
On azure we have the version 2.1.1 in which the package name(org.apache.commons.configuration2) differs from the 1.10 version ( org.apache.commons.configuration).
So having this line in the dependency A caused an error when using the 2.1.1 version:
Import org.apache.commons.configuration
It needs to be having "2" at the end, a thing I can t add as A is a dependency.
I tried excluding org.apache.commons:commons-configuration from A then using the maven shade plugin to rename the package but the jar file become double the actual size besides the shaded jar produced alone not inside the zip with the workflow and the sh file, a thing my team may not like.
Updating from commons-configuration 1 to 2 is a major change, the new version is not a drop-in replacement. As you have already pointed out the top level package changes and this will most likely brake library A. The correct solution will probably be to update library A to use commons-configuration 2.
You can still try to hack the Maven project setup to see if it works:
Exclude commons-configuration 1 from library A dependency using <exclude> tag.
Add commons-configuration 2 as a direct project dependency with provided scope in module B. The provided scope is needed to avoid packaging the dependency.
If you want to avoid using the maven-shade plugin than an alternative solution might be to:
Exclude commons-configuration 1 in the library A dependency declaration;
Work out which classes and methods from commons-configuration 1 that library A uses (easy enough if you have the source code, otherwise a modern IDE will disassemble it for you);
Write your own versions of these classes and methods in your application that delegate to the commons-configuration2 implementation.
Note that commons-configuration2 is a part of the Apache Spark distribution and it cannot be ignored. It would need to be added to your project with <scope>provided</scope>.
If this is too hard then the maven-shade-plugin is your only viable solution.

Library Depending upon integrating application for Spring Version

So I am writing a library for some features and the inner library needs to use Spring. I don't want to put in the version of Spring in the inner library. I want that the application using the library defines the version of Spring to use.
Is this even possible? If yes, then how?
Maven wise, clearly your library needs to be dependent on spring because it has to be compiled somehow so at least spring annotations like #Autowire or #Configuration / #Bean need to be in the compilation classpath.
However in the pom.xml of the library you can declare the dependency on spring as "optional" (<optional>true</optional>)
So when maven will compile the application that has your library as a dependency won't need to "take" transitively the spring as well
You can read about optional dependencies here. Their example with ProjectA, ProjectB and ProjectX is relevant...

slf4j-log4j12-1.7.2.jar unwanted dependency

I'm working in a multi module maven eap project. Previously it was implemented to use slf4j to use as logging framework. I changed it's logging configuration to use log4j2 as the underlying logging framework (still uses the slf4j). I referred to this document when I do so. But when I build the project and deploy it in jboss I get the following error.
Class path contains multiple SLF4J bindings, Found binding in xxx/lib/log4j-slf4j-impl-2.0.2.jar/org/slf4j/impl/StaticLoggerBinder.class and xxx/lib/slf4j-log4j12-1.7.2.jar/org/slf4j/impl/StaticLoggerBinder.class
P.S: I never add the slf4j-log4j12-1.7.2.jar dependency to pom.xml or in any of sub modules. I have no idea how that dependency is copied in to the lib folder.
Any comments guys ?
Well as it says it means you have indeed several slf4j bindings in your project.
You are right to deal with it now as it can become nasty and hide logs.
You should run
mvn dependency:tree
to see which of your modules adds the dependency to slf4j-log4j12-1.7.2.jar. It is probably that you have a transitive dependency to it.
You problem has in fact several solutions:
you can exclude slf4j-log4j explicitely
you can use the "provided" scope
you can use empty artifacts
I am referring to the following FAQ. It is about excluding commons-logging, but should be the same for you with slf4j-log4j.
When I ran into the same kind of problems, I found solution 2 to be the easiest to set and maintain. But solution 3 should work fine as well.

Building spring org.springframework.cglib.proxy source code not found

I'm diving into spring's source code,but when I did that,it showed me some errors about the cglib classes-Saying that the compiler can not find the classes.
Something like these classes:
Callback,CallbackFilter,Enhancer,MethodInterceptor,etc.
All these classes are in cglib package,but when I check the github for the latest source code(I updated my repository to make sure it is the latest master branch.),I can not found the classes too.
I checked spring's release package,it contains the classes listed above.
Is anyone can tell me,whether there is something wrong with spring's source code?Or if I'm in the wrong way,that the classes is generated by the cglib itself,not by someone else?
Thanks.
CGLib is being replaced by Javassist in the master branch (for 4.x release) probably. You need to check 3.x branches on GitHub to find the source codes.
UPDATE: seems that this is not the case. Related issue https://jira.springsource.org/browse/SPR-8190 is still on backlog.
UPDATE2: These classes are just copies of classes from CGLIB. Check JavaDoc for the package http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/cglib/package-summary.html:
Spring's repackaging of net.sf.cglib 3 (for internal use only).
This repackaging technique avoids any potential conflicts with
dependencies on CGLIB at the application level or from other
third-party libraries and frameworks.
As this repackaging happens at the classfile level, sources and
Javadoc are not available here. See the original CGLIB 3 Javadoc for
details when working with these classes.

Provided dependency in library, using previous version in project

If a library declares provided dependency on eg servlet-api using v3.0.1; would it be possible for users to use version 2.5 for their library, that will be used on third party web application?
In other words:
mylib (srv 3.0.1) <-- some_framework(srv 2.5) <-- user_webapp (tomcat 6 or 7)
Moreover: v2.5 is declared as javax.servlet:servlet-api:2.5 and version v3.0.1 is declared as javax.servlet:javax.servlet-api:3.0.1, so there is a difference.
Would it be a problem for some_framework to specify different servlet-api dependency (eg 2.5) than defined as provided in mylib (eg 3.0)? I assume that since scope is provided (and available only in compile time), dependency tools (mvn, gradle...) will not download it in some_framework, and they have (and are allowed) to declare dependency manually.
(yeah, i am aware of differences between 3.0 and 2.5, and that is not a question. I also assume everything compiles correctly, etc. I am just interested how maven would compile some_framework, on which dependency: 2.5 or 3?).
Let me answer my own question, as [SO] never helped with tricky ones:)
I created simple maven project (that will act as some_framework). It depends on jodd-servlet (mylib), that has servlets 3.0.1 listed as provided dependency. When I run
mvn dependency:resolve
i do not see servlets in the list of dependencies. Now, if current project (i.e. some_framework) lists servlets v2.5 as dependency; and then if I run the same command again, I see only dependency on 2.5.
Therefore, we may say that provided dependencies are not transparent or exported.

Categories