Код, запущенный под ant, не находит файл свойств, пока я не разветвлю JVM - PullRequest
1 голос
/ 09 мая 2011

Я только начинаю с Ant, и у меня возникают проблемы с получением цели "run" для работы. Часть моего кода загружает файл свойств, и он всегда не может найти этот файл, если я не заставлю свою цель выполнения использовать новую JVM. Ниже приведен очень упрощенный пример, цель «run» не выполняется, цель «run_fork» работает. Насколько я понимаю, у Ant есть собственный загрузчик классов, который заменяет загрузчик по умолчанию, поэтому я представляю, что это каким-то образом портит путь поиска. Можно ли как-нибудь изменить свой код, чтобы он работал без необходимости разворачивать новую JVM?

build.xml:

<project name="PropsExample" default="compile" basedir=".">

<property name="src" location="src"/>
<property name="bin" location="bin"/>

<target name="init">
    <tstamp/>
    <mkdir dir="${bin}"/>
</target>

<target name="compile" depends="init">
    <javac includeAntRuntime="false" srcdir="${src}" destdir="${bin}"/>
    <copy todir="${bin}">
        <fileset dir="${src}" includes="**/*.properties"/>
    </copy>
</target>

<target name="clean">
    <delete dir="${bin}"/>
    <delete dir="${dist}"/>
</target>

<target name="run" depends="compile">
    <java classname="com.example.Test">
        <classpath>
            <pathelement location="${bin}"/>
        </classpath>
    </java>
</target>

<target name="run_fork" depends="compile">
    <java fork="true" classname="com.example.Test">
        <classpath>
            <pathelement location="${bin}"/>
        </classpath>
    </java>
</target>

пример кода:

package com.example;

import java.util.Properties;
import java.io.InputStream;

public class PropertiesLoader {

    public static String getProperty() throws Exception {

        InputStream in = ClassLoader.getSystemResourceAsStream("com/example/test.properties");
        if ( in == null ) {
            throw new Exception("Cannot find test.properties");
        }
        Properties p = new Properties();
        p.load(in);
        in.close();
        return p.getProperty("test");
    }
}

и

package com.example;

public class Test {

    public static void main(String[] args) throws Exception {

        try {
            System.out.println(PropertiesLoader.getProperty());
        } catch ( Exception e ) {
            e.printStackTrace(System.out);
        }
    }
}

1 Ответ

2 голосов
/ 09 мая 2011

ANT, уже запущенный к тому моменту, когда он читает XML-файл, содержащий указанный путь к классу вашего прогона, фактически не может сбросить путь к классу работающей JVM.Вместо этого он пытается добавить к нему цепочку загрузчиков классов;однако ваш вызов загрузчику классов, вероятно, захватывает корневой загрузчик классов.Возможно, вы захотите сделать что-то вроде этого:

this.getClass().getClassLoader().getResourceAsStream("com/example/test.properties");

, что заставит класс использовать тот же загрузчик классов, с которым он был загружен.Это должно (надеюсь) перейти в цепочку ClassLoader в нужном месте, как если бы он загрузил текущий класс и файл свойств соответствующим образом «переместился» вместе с текущим классом, тогда файл свойств должен быть доступен через тот же загрузчик классов.

Обратите внимание, что есть много веских причин для того, чтобы разветвлять JVM.Самое важное, на мой взгляд, это избавить всю JVM от классов, связанных с ANT.Вы не хотите случайно привязывать вашу среду выполнения к классам, которые доступны только во время процесса сборки программного обеспечения, и если вы хотите привязать свои классы к ANT, им нужно управлять как сторонней библиотекой (чтобы вы могли контролировать версиион связывается со степенью связывания, способностью одинаково воспроизводить сборку для нескольких версий / выпусков ANT и т. д.)

...