PlayFramework项目中MDB数据库文件相对路径配置问题求助
Hey Felix, I’ve run into similar path headaches with Play Framework before—let’s break down why your relative path isn’t working and how to fix it properly.
Why Your Current Relative Path Fails
The ../../resources/DataposCO.mdb path relies on the runtime working directory matching your expected folder structure, which isn’t guaranteed in Play. When you run the app via sbt run or package it into a jar, the working directory might be the project root, target/, or even a completely different location depending on deployment. Hardcoding relative parent paths like ../ is fragile and error-prone.
Recommended Solutions
1. Use Classpath Resource Loading (Most Reliable)
If you place your .mdb file in src/main/resources (the standard directory for non-code resources in Play/SBT projects), you can load it via the classpath—this works seamlessly both in development and production.
Here’s how to adjust your code:
// In your DAO/DTO class URL dbResourceUrl = getClass().getResource("/DataposCO.mdb"); if (dbResourceUrl == null) { throw new RuntimeException("Could not find DataposCO.mdb in resources directory!"); } // Decode the URL path to handle spaces or special characters (e.g., %20 becomes a space) String msAccDB = java.net.URLDecoder.decode(dbResourceUrl.getPath(), "UTF-8"); String dbURL = "jdbc:ucanaccess://" + msAccDB; // Proceed with your database connection logic
- Note: If you package your app as a jar, the resource will be inside the jar. UCanAccess can read from jar resources, but if you need to write to the database, you’ll need to copy the
.mdbfile to a temporary external directory first (since jars are read-only).
2. Use Play’s Environment API (For External Files)
If you want to keep the .mdb file outside the classpath (e.g., in a resources folder at the project root), use Play’s Environment API to get the app’s root directory and construct the path safely.
For Play 2.6+ (which uses dependency injection):
import play.Environment; import javax.inject.Inject; import java.io.File; public class YourDatabaseDao { private final Environment environment; // Inject Environment via constructor (Play handles this) @Inject public YourDatabaseDao(Environment environment) { this.environment = environment; } public void connectToDatabase() { // Path relative to your Play app's root directory File dbFile = environment.getFile("resources/DataposCO.mdb"); if (!dbFile.exists()) { throw new RuntimeException("Database file not found at: " + dbFile.getAbsolutePath()); } String msAccDB = dbFile.getAbsolutePath(); String dbURL = "jdbc:ucanaccess://" + msAccDB; // Your connection code here } }
This method ensures the path is resolved relative to the actual app root, regardless of where the app is running.
Quick Checks to Avoid Issues
- File Permissions: Make sure the
.mdbfile has read/write permissions (Access databases require write access for locking and updates). - UCanAccess Dependencies: Double-check that you have the correct UCanAccess dependencies in your
build.sbt(e.g.,org.apache.derby:derby:10.14.2.0andnet.sf.ucanaccess:ucanaccess:5.0.1). - Resource Placement: If using classpath loading, confirm
DataposCO.mdbis insrc/main/resourcesand gets copied to thetarget/scala-xx/classesdirectory during compilation.
内容的提问来源于stack exchange,提问作者Felix

