问题
I'm writing a system, which will consist of
- proprietary, closed-source core component and
- several plugins, which I intend to distribute with their source.
For now, these are simply Maven projects, let's say myapp-core
(proprietary) and myapp-plugin1
(distributed with the source code).
myapp-plugin1
uses myapp-core
in the following way. There is a main class in myapp-plugin1
:
public class DisplayHouseholdsOnMapApp {
public static void main(final String[] aArgs) {
CoreApp app = new CoreApp();
try {
app.run(new MenuBarFactory(), new GlassPaneDisplay());
} catch (final IOException | ClassNotFoundException | SQLException exception) {
exception.printStackTrace();
}
}
}
CoreApp
is defined in the myapp-core
project, everything else (MenuBarFactory
, GlassPaneDisplay
) - in the myapp-plugin1
project.
Inside CoreApp.run
several things happen. Among other things, it tries to load data from files stored in myapp-core/src/main/resources
folder.
When I launch myapp-plugin1
, I get errors - classes defined in myapp-core
cannot load files defined in that folder.
Now I read these data using constructs like
import com.google.common.io.Files;
final List<String> lines = Files.readLines(aFile, Charsets.UTF_8);
How can I read these files in myapp-core
so that it works, when I use that project in myapp-plugin1
?
Update 1: The stack traces.
java.io.FileNotFoundException: src\main\resources\XXXX.csv (Das System kann den angegebenen Pfad nicht finden)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:131)
at com.google.common.io.Files$FileByteSource.openStream(Files.java:127)
at com.google.common.io.Files$FileByteSource.openStream(Files.java:117)
at com.google.common.io.ByteSource$AsCharSource.openStream(ByteSource.java:404)
at com.google.common.io.CharSource.getInput(CharSource.java:87)
at com.google.common.io.CharSource.getInput(CharSource.java:63)
at com.google.common.io.CharStreams.readLines(CharStreams.java:325)
at com.google.common.io.Files.readLines(Files.java:747)
at com.google.common.io.Files.readLines(Files.java:718)
18:19:29.896 [AWT-EventQueue-0] ERROR r.a.c.p.impl.gui.PrimCityGlassPane -
java.io.FileNotFoundException: src\main\resources\XXX.csv (Das System kann die angegebene Datei nicht finden)
at java.io.FileInputStream.open(Native Method) ~[na:1.8.0-ea]
at java.io.FileInputStream.<init>(FileInputStream.java:131) ~[na:1.8.0-ea]
at com.google.common.io.Files$FileByteSource.openStream(Files.java:127) ~[guava-15.0.jar:na]
at com.google.common.io.Files$FileByteSource.openStream(Files.java:117) ~[guava-15.0.jar:na]
at com.google.common.io.ByteSource$AsCharSource.openStream(ByteSource.java:404) ~[guava-15.0.jar:na]
at com.google.common.io.CharSource.getInput(CharSource.java:87) ~[guava-15.0.jar:na]
at com.google.common.io.CharSource.getInput(CharSource.java:63) ~[guava-15.0.jar:na]
at com.google.common.io.CharStreams.readLines(CharStreams.java:325) ~[guava-15.0.jar:na]
at com.google.common.io.Files.readLines(Files.java:747) ~[guava-15.0.jar:na]
at com.google.common.io.Files.readLines(Files.java:718) ~[guava-15.0.jar:na]
Update 2:
I tried to read the data using following code.
import com.google.common.io.Resources;
import com.google.common.base.Charsets;
final URL resource = getClass().getClassLoader().getResource(aFile.getPath().substring
("src\\main\\resources\\".length()));
final List<String> lines = Resources.readLines(resource, Charsets.UTF_8);
But now, when I run myapp-plugin1
I get following exception.
Exception in thread "main" java.lang.NullPointerException
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:192)
at com.google.common.io.Resources$UrlByteSource.<init>(Resources.java:79)
at com.google.common.io.Resources$UrlByteSource.<init>(Resources.java:74)
at com.google.common.io.Resources.asByteSource(Resources.java:68)
at com.google.common.io.Resources.asCharSource(Resources.java:113)
at com.google.common.io.Resources.newReaderSupplier(Resources.java:104)
at com.google.common.io.Resources.readLines(Resources.java:154)
at com.google.common.io.Resources.readLines(Resources.java:176)
回答1:
Sure you can use one artifact in an other with a dependency but you ask for resources. So here how you can do, use the maven-dependency-plugin with the goal: unpack, take care you unpack in a phase befor you need them. All the unpacked staff you can place in outputDirectory=target/classes Here an example with unpacking of two artifacts with the maven-dependency-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>target/classes</outputDirectory>
<includes>**/*.class,**/*.xml</includes>
</artifactItem>
<artifactItem>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>target/classes</outputDirectory>
<includes>**/*.class</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
来源:https://stackoverflow.com/questions/23409142/how-to-package-resources-so-that-they-can-be-accessed-from-other-maven-artifacts