How do I get Eclipse to get all of my resources on Tomcat's classpath?
I am having a devil of a time getting Eclipse to run my webapp on tomcat with the classpath correct. I have some spring configuration that references property files at classpath:/whatever.properties - these properties files live in my web project at src\main\resources, and I can see that they get deployed to the WEB-INF\classes folder, but they are not picked up. Also, a breakpoint in my custom spring property provider is not hit, even though the code is run (verified through logging).
.project snippet:
<buildSpec>
<buildCommand>
<name>org.maven.ide.eclipse.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</a开发者_运维问答rguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.maven.ide.eclipse.maven2Nature</nature>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
</natures>
.classpath snippet:
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry combineaccessrules="false" kind="src" path="/OtherProject"/>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Tomcat v5.5 Server"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.5.0_16"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
org.eclipse.wst.common.component:
<project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="Web Module">
<wb-resource deploy-path="/" source-path="/src/main/webapp"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<dependent-module deploy-path="/WEB-INF/lib" handle="module:/resource/OtherProject/OtherProject">
<dependency-type>uses</dependency-type>
</dependent-module>
<property name="context-root" value="WebModule"/>
<property name="java-output-path"/>
</wb-module>
</project-modules>
I have tried with Tomcat's Location (right click the server, select Properties) being in workspace metadata, and also with it living in the Servers project. I have tried using the workspace metadata deployment, letting eclipse take over my tomcat installation, and a custom deployment location. It has worked once - breakpoint hit, properties read - but when I started the server again the next time, it went back to its old ways.
If you need more information, let me know and I'll edit the post ASAP.
Some background on deploying to Tomcat using the Eclipse tooling: 1. Your Web projects will be bundled and copied to a single location. This location is then used as the location of a Web application for Tomcat. 2. The .project and .classpath files are not used as part of the deployment to Tomcat. These are development time artifacts specific to the Eclipse workbench.
Did you confirm that the properties files are deployed correctly to the bundled project location (1 above)?
I have created this code (hope it helps):
@Slf4j
public class ClasspathLibrariesParser {
private static final List<String> ALLOWED_KINDS = Arrays.asList("lib", "con");
private static final SAXParserFactory PARSER_FACTORY = ClasspathLibrariesParser.createParserFactory();
private static SAXParserFactory createParserFactory() {
final SAXParserFactory parserFactory = SAXParserFactory.newInstance();
parserFactory.setNamespaceAware(true);
return parserFactory;
}
public Set<String> parseClasspathFile() {
final File file = new File("./.classpath");
final Set<String> paths = this.parseClasspathFile(file);
return paths;
}
public Set<String> parseClasspathFile(final File file) {
try {
final Set<String> paths = new TreeSet<>();
final XMLReader parser = this.createClasspathFileParser(paths);
parser.parse(file.toURI().toURL().toString());
return paths;
} catch (Exception e) {
log.error("An error happened while parsing the classpath file \"{}\". Exception: {}", file, e.getMessage());
return null;
}
}
private XMLReader createClasspathFileParser(final Set<String> paths)
throws SAXException, ParserConfigurationException {
final XMLReader parser = PARSER_FACTORY.newSAXParser().getXMLReader();
parser.setContentHandler(new DefaultHandler() {
@Override
public void startElement(final String uri, final String localName, final String qname,
final Attributes atts) {
if (!"classpathentry".equals(localName) || atts == null) {
return;
}
for (int i = 0; i < atts.getLength(); i++) {
log.debug("read classpathentry attributes [{}] {} -> {}", i, atts.getLocalName(i), atts.getValue(i));
}
final String kind = atts.getValue("kind");
if (kind != null && ALLOWED_KINDS.contains(kind)) {
final String path = atts.getValue("path");
paths.add(path);
}
}
});
return parser;
}
}
精彩评论