【问题标题】:Resources access problem from JAR来自 JAR 的资源访问问题
【发布时间】:2011-01-28 03:48:24
【问题描述】:

我有一个项目的目录结构如下:

Eclipse 中的文件夹“项目”: --文件夹“src” --文件夹“资源” ----trayicon2.png --文件夹“db” ----test.db --文件夹“bin”

我正在使用以下方式访问图像:

Image image = Toolkit.getDefaultToolkit().getImage("resources/trayicon2.png");

从 Eclipse 中这不是问题。 然后我生成一个“可执行jar文件”,并添加dirs,目录结构为:

文件夹“项目” --文件夹“db” ----test.db --文件夹“资源” ----trayicon2.png --project.jar

现在无法再访问该图像了。此外,数据库不再可访问;在 Eclipse 中,我曾经通过以下方式访问它:

Connection conn = DriverManager.getConnection("jdbc:sqlite:db/test.db");

生成jar文件“project.jar”后如何访问资源(图像和数据库)?

【问题讨论】:

    标签: java resources jar


    【解决方案1】:

    您可能想要切换到ANT 来构建您的 jar 文件。

    您可以将图像资源内置到可以找到它们的 jar 中,以及任何所需的库(如 sqlite 的库,也可以放入 jar 内的 lib 文件夹中)。

    这是一个示例构建文件:

    <?xml version="1.0"?>
    <project name="test" default="compile" basedir=".">
        <description>
                Generates jar for project
     </description>
     <property name="src.dir" value="${basedir}/src"/>
        <property name="build.dir" value="${basedir}/build"/>
        <property name="build.classes" value="${build.dir}/classes"/>
        <property name="build.jars" value="${build.dir}/jars"/>
        <target name="init">
            <mkdir dir="${build.dir}"/>
            <mkdir dir="${build.classes}"/>
            <mkdir dir="${build.jars}"/>
        </target>
        <path id="core.classpath">
            <fileset dir="${build.jars}">
                <include name="**/*.jar"/>
            </fileset>
        </path>
        <path id='lib.classpath'>
            <fileset dir='lib' />
        </path>
    
        <target name="compile" depends="init">
            <javac srcdir="${src.dir}" destdir="${build.classes}" debug="true">
                <classpath refid="lib.classpath"/>
            </javac>
        </target>
    
     <target name="copy-resources">
            <copy todir="${build.classes}">
                <fileset dir="${src.dir}">
                    <exclude name="**/*.java"/>
                </fileset>
            </copy>
        </target>
    
        <target name="jar" depends="compile, copy-resources">
            <jar destfile="${build.jars}/project.jar">
                <fileset dir="${build.classes}">
                    <include name="**/*.class"/>
                    <include name="**/*.properties"/>
                    <include name="**/*.png"/>
                </fileset>
             <fileset dir=".">
              <include name="**/*.jar"/>
             </fileset>
             <manifest>
                    <attribute name="Built-By" value="${user.name}"/>
                 <attribute name="Main-Class" value="com.your.path.to.MainClass"/>
                </manifest>
            </jar>
        </target>
    
        <target name="clean">
            <delete dir="${build.dir}"/>
            <delete dir="${build.classes}"/>
            <delete dir="${build.jars}"/>
        </target>
    </project>
    

    这假设您在 src 目录中有一些 java 文件,在 lib 文件夹中有一些库。所以你的路径应该是这样的:

    Project
    ----------
    -bin
    -src
    --com...
    ---MainClass (has a main method, runs your program)
    ---a.png (will be findable)
    -lib
    --jar files required by your project
    build.xml
    -----------
    

    它还会复制您在 src 文件夹中的任何属性或 png 文件。

    然后您将在 build.xml 级别键入 ANT jar 来构建 jar 文件。

    【讨论】:

      【解决方案2】:

      当您在 eclipse 中时,您传递的文件名是相对的,并且可以使用 eclipse 自动设置的类路径正确解析。尝试使用该方法的 URL 版本并将 URL 传递给您的 jar 文件。你可以看到example on this page

      【讨论】:

        【解决方案3】:

        对于图片,试试这个:

        URL imageURL = getClass().getResource("/resource/trayicon2.png"); // note leading slash
        Image image = Toolkit.getDefaultToolkit().getImage(imageURL);
        

        【讨论】:

        • 谢谢,这适用于图像(尽管使用“资源”)。我以前试过这个,但我省略了斜线;显然这是问题所在。如果我也找不到访问数据库的方法,我会接受这个答案。再次感谢您。
        • 接受这个答案。在我的 Ubuntu Linux 上,当右键单击/“使用 Sun Java 6 运行时打开”打开文件时,它会打开带有空数据库的应用程序;虽然在编写“java -jar project.jar”时它会使用完整的数据库打开它。我会尝试解决这个问题,如果我在 Google 中找不到任何信息,可能会问另一个问题。关于这个问题,你的回答是正确和准时的,对我有帮助。谢谢。
        【解决方案4】:

        您不能直接访问 JAR 文件中的资源。相反,您需要使用类的URL getResource(String)(或InputStream getReourceAsStream(String))方法。

        不过,我不确定您如何将它与 SQLite 数据库一起使用。

        【讨论】:

          猜你喜欢
          • 2011-02-08
          • 2012-11-28
          • 2016-12-29
          • 2012-05-11
          • 2020-01-31
          • 2015-09-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多