Spring Aop Dependencies - java

NOTE: Please ignore if I ask any kind of stupid questions. Apologies in advance.
PROBLEM: I am new to spring and spring-aop. Everything was going great untill #Aspect annotation is used in java class and aop:aspectj-autoproxy in spring.xml
I have included following jars in runtime classpath:
aspectjrt.jar
aspectjweaver.jar
cglib.jar
asm.jar
aopalliance.jar
Now i am facing an issue of NoClassDefFoundError for org.aspectj.lang.annotation.Around.class although this class exist in aspectjrt.jar
NOTE: I am using Spring-4.1
QUESTION: What are the jars that are required for Spring-AOP? If I have all the jars (as far as i have searched, i have all the jars that are required), then is there any version compatibility issue.
Any kind of help will be much appreciated.

Did you add spring-aop? The easiest way would be to use maven for building (or similar dependency management tool) and add dependency to spring-aop
http://mvnrepository.com/artifact/org.springframework/spring-aop/4.1.0.RELEASE

As of Spring 3.2, it is no longer necessary to add CGLIB to your project classpath, so when using Spring-4.1 you can ignore it
the only jar you need to work Aop on spring project is is aspectjweaver,
version 1.6.8 or later This library is available in the 'lib' directory of an AspectJ distribution or via the Maven Central repository.=> here

Related

Spring boot: Will a library get dependency from the parent app/service

I am using spring-retry in my spring-boot service, as well as spring-boot library.
I Noticed this scenario to work:
Use spring retry logic in the library, but the spring retry jars are not imported in the library
Use the library in the parent service as a maven dependency.
The parent service imports spring-retry maven jars.
Is is normal for the library code to use the maven jars from the parent app ? and not need to import the jars itself ? My common intuition says it should, as the resulting compilation unit will have the dependencies injected.. but not sure.
Sorry if this is a super naive question, but my searches did not give a good answer (maybe want using the right keywords)
I'm not sure I've got you right, probably this question should be rephrased.
So you say, that there is a "spring-boot library" that uses spring retry logic.
If so, this library has a maven module and it gets compiled into a regular jar, right?
But if so, if it uses classes/interfaces/annotations from spring retry library and doesn't have it on the compile class path how it gets compiled? I believe you do have this spring retry library in the dependencies but just don't notice (try mvn dependency:tree in the spring boot library module to see the dependencies)
Other than that - usually when you develop a library its intended to be reused by different applications, and if it has dependencies on its own, usually it should list them in the project's library pom. Also usually people who develop the library try to minimize the dependencies list of the library itself.
So if pom.xml of the library doesn't list the required dependencies it won't even compile.
Now in runtime, all the dependencies (including transitive of course) should be available to the spring boot application, otherwise the class that uses these dependencies might not load. But other than that, spring, being a runtime framework, doesn't really care how did the dependency find its way into BOOT-INF/lib folder - its expected to work as long as the dependency is there.

How to build a library around spring-boot that doesn't enforce a certain spring-boot version?

I am trying to build a library https://github.com/mhewedy/spring-data-jpa-mongodb-expressions on top of spring boot and spring Data JPA.
What I want to achieve and hence the library doesn't use explicitly implementation feature of spring boot or spring data JPA, I need to make this a library to take the version from the including project.
Currently, the version of spring boot is defined in the pom.xml
So, I think once I uploaded the jar to the maven repository, and whenever anybody depends on this jar, there might be a conflict in the spring dependencies (that comes from his project and what comes from this jar)
So my question is If I make the dependencies in pom.xml as Optional, do this will solve the problem? if not what other alternative solutions I can do?
EDIT:
Here's a list of types from spring I use in the library:
org.springframework.data.jpa.repository.JpaRepository;
org.springframework.data.repository.NoRepositoryBean;
org.springframework.data.domain.Page;
org.springframework.data.domain.Pageable;
org.springframework.data.domain.Sort;
org.springframework.data.jpa.domain.Specification;
org.springframework.data.jpa.repository.support.JpaEntityInformation;
org.springframework.data.jpa.repository.support.SimpleJpaRepository;
For building your library, you need to use a given version of the dependencies. You need to choose one, otherwise the compiler cannot create a classpath and compile your code.
Somebody who uses your library might use another version of the dependencies. Their versions will (usually) override your versions because they win in the Maven dependency mediation. So your library will actually run with the versions that the library user specifies (if the library user does not use your dependencies, then your versions are still there).
So, the question that remains is: Will your code work with a newer/different version of the dependencies?
This cannot be said in general because it depends on the way the maintainer of the dependencies works.

wildfly 10 - javax.servlet.ServletContainerInitializer: Provider org.springframework.web.SpringServletContainerInitializer not a subtype

I am using Spring 4.3 and Servlet 3.1.
Deployment fails with error
javax.servlet.ServletContainerInitializer: Provider org.springframework.web.SpringServletContainerInitializer not a subtype.
I know that it is some wrong class is loading
The Spring jars and Servlet 3.1 jars are configured as a module and mentioned in module.xml.
javax.servlet.ServletContainerInitializer is present in only one jar jboss-servlet-api_3.1_spec-1.0.0.Final.jar that I have included in module.xml.
SpringServletContainerInitializer is needed for my application.
Let me know if you need me to post more details.
Any help is appreciated.
I had the same problem and solved it by goig through my dependencies to see if anything crashed with my application-servers libraries.
Make sure your java-ee and java-ee-web dependencies are set to "provided" scope in your maven/gradle configuration.
I was getting the same error and after researching, I identified somehow SpringServletContainerInitializer was not loading because of Maven packaging issue. In my case, spring-web-4.3.8.Release.jar was not bundling correctly with application WAR.
This can be fixed by
resolving application bundling conflict
using server shared libraries
if using IDE for application bundling, one can avoid bundling using IDE or switch the IDE (like STS to Eclipse/RAD)
Another potential source of extra copies of servlet-api and other similar Java EE APIs is Spring Boot's tomcat-embed-core-<version>.jar, which you may get from spring-boot-starter-web.

Atlassian FishEye plugin and Spring LDAP classes

My plugin for FishEye should have a possibility to accessing the our Active Directory and implement some more features for FishEye. The plugin should make the synchronization with directory every X minutes, so it is based on SAL Scheduler.
When I tried to use com.sun.jndi.ldap.LdapCtxFactory, I found that is works only with REST plugin, but using with SAL does not load this classes even when I re-defined the classloader.
Anyway, I re-implemented my functionality with the Spring LDAP and when I tried to deploy my plugin to the FishEye I got:
2014-12-03 23:12:03,010 ERROR [ThreadPoolAsyncTaskExecutor::Thread 9 ] org.springframework.osgi.extender.internal.activator.ContextLoaderListener DefaultOsgiBundleApplicationContextListener-onOsgiApplicationEvent - Application context refresh failed (NonValidatingOsgiBundleXmlApplicationContext(bundle=com.mycompany.fisheye.ldap-restriction-plugin, config=osgibundle:/META-INF/spring/*.xml))
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/osgi]
Offending resource: URL [bundle://84.0:0/META-INF/spring/atlassian-plugins-component-imports.xml]
Ok. I googled and found https://developer.atlassian.com/docs/faq/troubleshooting/dependency-issues-during-plugin-initialisation
There is written that I have to change the scope of dependency to provided for avoiding the conflicts. Ok, I made that. But now I have another exception:
Exception in thread "PluginSchedulerTask-com.mycompany.fisheye.LdapRestrictio nComponentImpl:job" java.lang.NoClassDefFoundError: org/springframework/ldap/core/support/LdapContextSource
I tried to put the spring-ldap-core-1.3.2.RELEASE.jar to $fisheyeDir/lib and nothing happens - the bootloader does not pick up this JAR.
Does anybody know what can be done in this situation? Should I use another LDAP framework or it is possible to shove these ldap client implementation to the classpath?
FishEye version 3.6.1 (latest), spring jars into classpath version 3.0.5.RELEASE. My spring-security-ldap dependency is also 3.0.5.RELEASE.
Thanks in advance.
The Spring version FishEye uses internally (3.0.5 in 3.6.1, 3.1.4 as of 3.7), is not exposed to plugins.
Instead they get a spring runtime from the Atlassian plugin system (https://bitbucket.org/atlassian/atlassian-plugins). FishEye uses plugins 3.0.x, so the Spring version that's available to plugins is 2.5.6.
Neither FishEye, the plugin system nor any of the bundled plugins include spring-ldap, so you can't set the dependency scope to (as this causes the library not to be included in the plugin jar, instead expecting it be available via an OSGI import).
So what I believe you should try is to bundle a version of spring-ldap that's compatible with Spring 2.5.6. To solve the BeanDefinitionParsingException, you might need to exclude some transitive dependencies that are provided by the plugin system (use mvn dependency:tree to find those).
Disclosure: I'm a dev working on FishEye/Crucible

Indirectly referenced from required .class files

I'm getting below error in STS:
The type org.springframework.core.env.EnvironmentCapable cannot be resolved. It is indirectly referenced from required .class files
This sounds like a transitive dependency issue. What this means is that your code relies on a jar or library to do something - evidently, you depend on Spring framework code. Well, all that Spring code also depends on libraries and jars.
Most likely, you need to add the corerctly versioned org.springframework.core jar to your classpath so that the EnvironmentCapable class can be found when your IDE attempts to build your project.
This might also be a jar collision issue as well, although that sounds less likely. When an application experiences jar collision (also known as "dll hell"), the compiler is finding multiple jars and classes with the same fully-qualified name. For example, let's say you added Spring to your classpath, along with the entire Tomcat server library. Well, those two jars may contain the same exact named classes, maybe the same version, maybe different versions. But either way, when the compiler looks for that EnvironmentCapable class, it finds two (in this contrived example) - one in the Spring jar and one in the Tomcat jar. Well, it doesn't know which one to choose, and so it throws a ClassDefNotFoundException, which would/could manifest itself as the error you experienced.
I faced same error while i work with spring security on spring-security-config.i jsut deleted that jar in maven repo and gave maven->update Project in eclipse.
it is resolved.Please try it once.
From command line, run "mvn clean install", you'll see project failed and you'll see artifacts in the logs that cause such a problem.
After that, remove artifacts from .m2/repository, then maven update from eclipse.
To avoid jar collision, make sure you declare your dependency versions under the properties tag in the aggregate pom.xml, and use the property name as a placeholder throughout the project. For example 4.2.5.RELEASE in the parent pom, and then in the child modules just use ${spring.version} instead of 4.2.5.RELEASE. This way you can avoid having two different versions of the same library on the classpath.
Also it is recommended to be consistent with the version of spring dependencies. Use the same version for spring-core, spring-web etc.
If you are using maven, then you can use the maven enforcer plugin to ensure dependency convergence, and avoid further issues with transitive dependencies.

Categories

Resources