简体   繁体   中英

Is it possible to get the directory of a class package within a .jar?

I am trying to get the directory of a class package as a File within my .jar (the hierarchy is /controller/core ):

File directory_file_of_package = new File(getClass().getResource("/controller/core").toURI());

Which works when I run the program within the IDE, but when I run it as a standalone .jar, it gives me this error:

java.lang.IllegalArgumentException: URI is not hierarchical

Looking at these questions ( why my URI is not hierarchical? and Java Jar file: use resource errors: URI is not hierarchical ) does not help me, because those questions involved obtaining a File within the .jar as a resource ( getResourceAsStream() ), but what I am trying to obtain is a directory.

Further, the accepted answer states this:

Generally the IDEs separates on file system classes and resources. But when the jar is created they are put all together.

So, is there no way to grab the directory of /controller/core ?

My XY Problem:

I am trying to read a .CSV file using CSVJDBC ( http://csvjdbc.sourceforge.net/ ), and the way the DriverManager references the CSV file as as if the containing folder is the database and the CSV file is the table .

public class SearchData {

    void SearchData() {
        try {
            Class.forName("org.relique.jdbc.csv.CsvDriver");

            File directory_file_of_package_containing_csv = new File(getClass().getResource("/controller/core").toURI());

            // Driver points to directory which contains the CSV file as if it is the database
            Connection conn = DriverManager.getConnection("jdbc:relique:csv:" + directory_file_of_package_containing_csv.toString());
            System.out.println("Connection established.");
            Statement stmt = conn.createStatement();
            System.out.println("Statement created.");

            // CSV is named "data.csv" so the CsvDriver sees "data" as the table name
            String sql = "SELECT id,name FROM data";

            ResultSet results = stmt.executeQuery(sql);

            ...

        } catch (ClassNotFoundException | SQLException | URISyntaxException e) {
            e.printStackTrace();            
        }
    }
}

How can I point CsvJdbc to my csv file contained within a .jar?

There simply is no directory of a package within the JAR. It works in IDE because your class is not yet packaged in a JAR file and resides in some directory. But this is not the case with JARs.

So if some of the libraries you use require a directory with a file in it, you can't generally achieve this with classpath resources. One of the options would be to create a copy of your resource as a file in a temporary directory.

Alternatively you may want to study the CsvJDBC documentation closer:

To read data that is either held inside the Java application (for example, in a JAR file) or accessed remotely (for example, using HTTP requests), create a Java class that implements the interface org.relique.io.TableReader and give this class name in the connection URL. CsvJdbc then creates an instance of this class and calls the getReader method to obtain a java.io.Reader for each database table being read.

So you should be able to solve this for CsvJDBC without temporary directories.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM