Maven: Inheriting resources of dependency - maven

I got a project that have a dependency to another one. In the second one, there are some resources. From the first one, I'm doing the following:
ClassLoader.getSystemResourceAsStream(filename);
It's failing to get the resource from the dependency. Any idea why this can happen?
Thanks,
Mooncrosser

If you're trying to load a file that's on the classpath you probably mean getResourceAsStream.
The other possibility is that when you're running it you're not running it with the full classpath.

Related

Spring Resource Loading

Can anyone explain how Spring decides where to look for resources when one uses the ResourceLoader.getResource(...) method?
I am having a problem with a multi-module maven application built using Spring Boot whereby in my integration tests my code is able to find resources using resourceLoader.getResource("templates/") or even resourceLoader.getResource("classpath:templates/"). So far so good...
However, when the module is eventually packaged into the executable JAR and run with embedded Tomcat the resources can no longer be resolved. I also tried resourceLoader.getResource("classpath*:templates/") with no success.
What I find concerning is that when I add a logging statement to output the URL being used in the search i get a path to one of the other modules in the project (not the one that actually contains the resource in question). E.g: jar:file:/Users/david/exmaple/target/spring-boot-0.0.1-SNAPSHOT.jar!/lib/module1-0.0.1-SNAPSHOT.jar!/templates/ whereas I believe the resource is in jar:file:/Users/david/exmaple/target/spring-boot-0.0.1-SNAPSHOT.jar!/lib/module2-0.0.1-SNAPSHOT.jar!/templates/
The resource loader was obtained from an Autowired constructor param.
Thanks in advance for any hints.
Edit
Just in case it isn't clear or is of importance, my integration tests for the module in question aren't aware of the other module. I have module1, module2 and a spring-boot module which has dependencies on module1 & module2. Essentially, when I run the integration tests for module 2 the classpath isn't aware of module1 - so I suspect that this has something to do with why it works in the tests.
When you use classpath: or classpath*: prefix, internally, this essentially happens via a ClassLoader.getResources(…​) call in spring.
The wildcard classpath relies on the getResources() method of the underlying classloader. As most application servers nowadays supply their own classloader implementation, the behavior might differ especially when dealing with jar files. A simple test to check if classpath* works is to use the classloader to load a file from within a jar on the classpath: getClass().getClassLoader().getResources("<someFileInsideTheJar>"). Try this test with files that have the same name but are placed inside two different locations. In case an inappropriate result is returned, check the application server documentation for settings that might affect the classloader behavior.
Do not use classpath: form as you have multiple classloader locations of templates/ .
Refer to: resources-classpath-wildcards

Maven ships dependencies inside war but not in jar

I have two maven projects, one (I will call it core) is an ejb-jar (ejb) and the other a war (client).
My client project consumes some ejbs inside my core...so far so good.
But I'm getting a ClassNotFoundException inside my core application because it can't find one class from apache-beanutils...I have set this dependency with compile scope in it's pom.xml but it does not get shipped inside the output jar.
When I check my client.war package I see every compile-scoped dependency inside the WEB-INF/lib folder...but in my core.jar I don't see any of it's dependencies...I'm totally confused about this.
Can someone help me? I tried to google it before asking but I didn't find anything useful so far..thanks.
You can use the maven assembly plugin to bundle all the jars in one super jar.
See this: question

Maven Jetty plugin with endorsed external directory

I have a project with more than an hundred external library dependencies, here we use tomcat with this endorsed jar libs configured on a directory in the server (now is under $CATALINA_HOME/lib/endorsed), so the webapp can access those resources on runtime start.
I wanted to try jetty instead, because tomcat takes too much memory and crashes frequently. Now I'm wondering if there is a parameter to pass on maven-jetty-plugin to specify this jar's folder so as the webapp class loader find them in its classpath.
I've tried extraClasspath in configuration tag, but it seems to load only classes and ignore all jars in the directory I set into (if I pass the full name path of the jar, it is loaded, but I don't want to set every library that I need there).
Thanks in advance for the help
update:I know it's not a standard maven operation, i'm searching for an emergency workaround since this project is very huge and I can't refactor as I want.
But also I expected this feature was not as tricky as it seemed to me at first glance.
You need to pass them as absolute paths, or, alternatively, have them as dependencies of the plugin itself.
What you want to have done goes against Maven's portability principles, so don't expect it to support it.

Understanding Maven scoping better

I have been struggling to figure out what's the use of scoping that is provided by Maven
as mentioned here.
Why should you not always have compile time scoping? Real life examples would be really appreciated.
The compile scoped dependencies are only used during compilation.
The test scoped ones -- only during tests. Say you have tests using junit, or easymock. You obviously do not want your final artifact to have a dependency on them, but would like to be able to just depend on these libraries while running your tests.
Those dependencies which are marked provided are expected to be on your classpath when you're running the produced artifact. For example: you have a webapp and you have a dependency on the servlet library. Obviously, you should not package it inside your WAR file, as the webapp container will already have it and a conflict may occur.
One of the reasons to have different scopes for dependencies is that different parts of the build can depend on different dependencies. For example, if you are only compiling your code and not executing any tests, then there is no point in having Maven downloading your test dependencies (if they're not already present in your local repository, of course). The other reason is that not all dependencies need to be placed in your final artifact (whether it's an assembly, or WAR file), as some of the dependencies are only used during the build and testing phases.
compile
Will copy these jar files into prepared War file.
Ex: hibernate-core.jar need to have in our prepared War.
provided
These jars will be considered only at complie time and test time
Ex:
servlet.jar will be provided by deployed server, so no need to provide from our prepared War file.
test
These jars are only required for running test classes.
Ex: Junit.jar will be required only for running Junit test classes, no need to deploy these.
Scopes are quite well explained in here:
https://maven.apache.org/pom.html#Dependencies
As a reference, I copied the paragraph:
scope: This element refers to the classpath of the task at hand
(compiling and runtime, testing, etc.) as well as how to limit the
transitivity of a dependency. There are five scopes available:
compile
- this is the default scope, used if none is specified. Compile dependencies are available in all classpaths. Furthermore, those
dependencies are propagated to dependent projects.
provided - this is
much like compile, but indicates you expect the JDK or a container to
provide it at runtime. It is only available on the compilation and
test classpath, and is not transitive.
runtime - this scope indicates
that the dependency is not required for compilation, but is for
execution. It is in the runtime and test classpaths, but not the
compile classpath.
test - this scope indicates that the dependency is
not required for normal use of the application, and is only available
for the test compilation and execution phases.
system - this scope is
similar to provided except that you have to provide the JAR which
contains it explicitly. The artifact is always available and is not
looked up in a repository.
there are a couple of reasons that you might not want to have all dependencies to be default compile scope
reduce the size of final artifact(jar,war...) by indicating different scope.
when you have a multiple-modules project, you have ability to let each module have it's own version of dependency
avoid class version collision by provided scope, for instance if you are going deploy a war file to weblogic server, you need to get rid of some javax jars, like javax.servlet, javax.xml.parsers, JPA jars and etc. otherwise you might end up with class collision error.

Grails dependency issues

I'm in the process of moving a Java/Spring MVC app to Grails. I was able to get a couple of pages along with Spring Security working. However, when I added cxf-bundle-minimal as a dependency I started to get the errors below.
::::::::::::::::::::::::::::::::::::::::::::::
:: UNRESOLVED DEPENDENCIES ::
::::::::::::::::::::::::::::::::::::::::::::::
:: javax.ejb#ejb;3.0: not found ::
::::::::::::::::::::::::::::::::::::::::::::::
Exception starting filter springSecurityFilterChain
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'springSecurityFilterChain' is defined
Now, even if I remove the dependency the error continues. Anyone know what the cause of the problem is and how to resolve it? My dependency list follows.
dependencies {
runtime 'mysql:mysql-connector-java:5.1.12'
compile('log4j:log4j:1.2.16',
'org.apache.cxf:cxf-bundle-minimal:2.2.9',
'org.springframework:spring-beans:3.0.2.RELEASE',
'org.springframework:spring-context:3.0.2.RELEASE',
'org.springframework:spring-core:3.0.2.RELEASE',
'org.springframework:spring-jdbc:3.0.2.RELEASE',
'org.springframework.security:spring-security-core:3.0.2.RELEASE',
'org.springframework.security:spring-security-config:3.0.2.RELEASE',
'org.springframework.security:spring-security-web:3.0.2.RELEASE')
}
This isn't what you want to hear, I'm sure, but nearly every time I've strayed from the default Grails configuration (using Maven or the native build), I've found myself beating my head against these types of configuration problems. I don't have a magical solution for you, but I'd first run a dependency report to see what the graph looks like (http://grails.org/doc/1.3.x/). After that it becomes detective work and more than a little trial-and-error. Anyway, start with the dependency report and see what it shows. Good luck.
Chances are you need to add a new maven repo dependency into your BuildConfig.groovy file. Find (or create) a repo that has the jar files that are missing, and add it in. By default the jboss maven repo is commented out, but it might have what you're looking for as a starting place.
I had a similar issue today. After some research online I decided that this problem may be caused by one of my plugin's dependencies, but I didn't know which one. How I solved (sidestepped) it was to go to "application.properties" and commented out the plugins that were non-essential.
Obviously this does not solve the underlying dependency problem, unless you can live without those plugins.
I understand your frustrations, believe me. If you find a better solution please post it!

Resources