In my Maven project there is one module (core) that has a few resources for its classes. When running classes inside the module its able to get its own resources. Everything works fine.
Where stuff breaks is when another module which depends on the core tries to run that class. The folder that Java is looking for resources in is this module, not the core module. So the class fails.
In short: How can I access the resources of a dependency?
I've experimented with trying to do this by declaring in Core's JAR Manifest Class-Path: .
. However when listing the resources available with JSHookLoader.class.getClassLoader().getResources("");
(JSHookLoader is in Core if it means anything), I get:
Resource: W:\programming\quackbot-hg\impl\target\classes File rebel.xml Resource: W:\programming\maven-repo\org\quackbot\core\3.5-SNAPSHOT File core-3.5-SNAPSHOT.jar File core-3.5-SNAPSHOT.pom File maven-metadata-local.xml File _maven.repositories
This of course complicates things as I expected the JAR itself to be in the Classpath, not the directory the JAR is in
Any suggestions?
Coming back to this project I still have this issue. Other guides have talked about using maven-assembly-plugin and the remote resources plugin, but thats a lot of pain as all modules have to include the monster plugin XML.
Why don't I simplify the question to this: How can I add a dependencies JAR to the resource list?
This should be simple enough, but how can I do it? I've spend hours trying to figure out a simple clean way to do it but to no avail.
Terraform uses this dependency information to determine the correct order in which to create the different resources. To do so, it creates a dependency graph of all of the resources defined by the configuration. In the example above, Terraform knows that the EC2 Instance must be created before the Elastic IP.
It's like you said; dependencyManagement is used to pull all the dependency information into a common POM file, simplifying the references in the child POM file. It becomes useful when you have multiple attributes that you don't want to retype in under multiple children projects.
The dependency plugin provides the capability to manipulate artifacts. It can copy and/or unpack artifacts from local or remote repositories to a specified location.
Right-click the utility project, and select Maven>Add Dependency. Type a dependency name in the Enter groupID… field (e.g., commons-logging) to search for a dependency. Select the dependency, and click OK.
After lots of searching I finally stumbled upon a solution.
My solution takes the core module and unpacks it with the Maven Dependency Plugin, making sure to exclude the META-INF folder and the org folder which is where the compiled classes are. The reason I'm excluding what I don't want instead of explicitly stating what I do want is so new resources can be added easily without me having to update my POM all the time.
The reason I'm not using the assembly plugin or the remote resources plugin is because they use dedicated resource modules. I don't think I should have to make a core module and a core-resources module, with the core-resources module only containing logback and hibernate configuration files + some other stuff.
Here is a copy of what I'm using to do this
<build> <plugins> <!--Extract core's resources--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.2</version> <executions> <execution> <id>unpack</id> <phase>generate-resources</phase> <goals> <goal>unpack-dependencies</goal> </goals> <configuration> <includeGroupIds>${project.groupId}</includeGroupIds> <includeArtifactIds>core</includeArtifactIds> <excludeTransitive>true</excludeTransitive> <overWrite>true</overWrite> <outputDirectory>${project.build.directory}/core-resources</outputDirectory> <excludes>org/**,META-INF/**,rebel.xml</excludes> <overWriteReleases>true</overWriteReleases> <overWriteSnapshots>true</overWriteSnapshots> </configuration> </execution> </executions> </plugin> </plugins> <!--New resource locations--> <resources> <resource> <filtering>false</filtering> <directory>${project.build.directory}/core-resources</directory> </resource> <resource> <filtering>false</filtering> <directory>${basedir}/src/main/resources</directory> </resource> </resources> </build>
If the resources are located in /src/main/resources
and classes in the JAR are accessing them using getResourceAsStream()
, you should be able to access these files from classes in other JARs as well (also using getResourceAsStream()
). This is because all the files located in /src/main/resources
eventually land in the same logical directory (CLASSPATH
). In other words: all the files located in /src/main/resources
and all the classes compiled from /src/main/java
are so to say merged into a single namespace.
If you still can't access files even though all the classes are using uniform getResourceAsStream()
API, you might have some class-loading visibility issues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With