Включение всех jar-файлов в каталог внутри Java classpath

Вот как я столкнулся с аналогичной проблемой в контексте ES6:

function merge(array1, array2, prop) {
    return array2.map(function (item2) {
        var item1 = array1.find(function (item1) {
            return item1[prop] === item2[prop];
        });
        return Object.assign({}, item1, item2);
    });
}

Примечание. Этот подход не возвращает никаких элементов из массива, которые не отображаются в массиве.


EDIT: У меня есть некоторые сценарии, где я хочу сохранить элементы, которые не отображаются во втором массиве, поэтому я придумал другой метод.

function mergeArrays(arrays, prop) {
    const merged = {};

    arrays.forEach(arr => {
        arr.forEach(item => {
            merged[item[prop]] = Object.assign({}, merged[item[prop]], item);
        });
    });

    return Object.values(merged);
}

var arr1 = [
    { name: 'Bob', age: 11 },
    { name: 'Ben', age: 12 },
    { name: 'Bill', age: 13 },
];

var arr2 = [
    { name: 'Bob', age: 22 },
    { name: 'Fred', age: 24 },
    { name: 'Jack', age: 25 },
    { name: 'Ben' },
];

console.log(mergeArrays([arr1, arr2], 'name'));
935
задан Maarten Bodewes 8 June 2017 в 08:47
поделиться

9 ответов

Думайте о файле банки как о корне структуры каталогов. Да, необходимо добавить их всех отдельно.

1
ответ дан R. Van Hoose 8 June 2017 в 08:47
поделиться

Необходимо добавить их всех отдельно. С другой стороны, если Вы действительно потребность просто определить каталог, можно не сотрясать все в один dir и добавить это к пути к классу. Я не рекомендую этот подход однако, поскольку Вы рискуете причудливыми проблемами в управлении версиями пути к классу и unmanagability.

1
ответ дан Daniel Spiewak 8 June 2017 в 08:47
поделиться

Если действительно необходимо определить все .jar файлы динамично, Вы могли бы использовать сценарии оболочки, или Муравей Apache . Существует проект свободного городского населения, названный Средство запуска палаты общин , который в основном позволяет Вам определить свой сценарий запуска как файл типа "build" муравья (если Вы видите то, что я имею в виду).

Затем можно определить что-то как:

<path id="base.class.path">
    <pathelement path="${resources.dir}"/>
    <fileset dir="${extensions.dir}" includes="*.jar" />
    <fileset dir="${lib.dir}" includes="*.jar"/>
</path>

В Вашем файле типа "build" запуска, который запустит Ваше приложение с корректным путем к классу.

9
ответ дан 8 June 2017 в 08:47
поделиться

Используя Java 6 или позже, опция пути к классу поддерживает подстановочные знаки. Отметьте следующее:

  • Использование прямо заключает в кавычки (")
  • Использование *, не *.jar

Windows

java -cp "Test.jar;lib/*" my.package.MainClass

Unix

java -cp "Test.jar:lib/*" my.package.MainClass

, Это подобно Windows, но использует : вместо ;. Если Вы не можете использовать подстановочные знаки, bash позволяет следующий синтаксис (где lib каталог, содержащий все архивные файлы Java):

java -cp $(echo lib/*.jar | tr ' ' ':')

(Отмечают, что использование пути к классу является несовместимым с -jar опция. См. также: Выполняют файл банки с несколькими библиотеками пути к классу от командной строки )

Подстановочные знаки Понимания

От Путь к классу документ:

записи Пути к классу могут содержать подстановочный символ * базового имени, который считают эквивалентным определению списка всех файлов в каталоге с расширением .jar или .JAR. Например, запись пути к классу foo/* определяет все файлы JAR в каталоге, названном нечто. Запись пути к классу, состоящая просто из [1 115], расширяется до списка всех файлов банки в текущем каталоге.

запись пути к классу А, которая содержит *, не будет соответствовать файлам класса. Для соответствия обоим классам и файлам JAR в единственном нечто каталога используйте или foo;foo/* или foo/*;foo. Выбранный порядок определяет, загружаются ли классы и ресурсы в [1 119] перед файлами JAR в [1 120], или наоборот.

Подкаталоги не ищутся рекурсивно. Например, foo/* ищет файлы JAR только в [1 122], не в [1 123], foo/baz, и т.д.

порядок, в котором файлы JAR в каталоге перечисляются в расширенном пути к классу, не определяется и может варьироваться от платформы до платформы и даже с момента до момента на той же машине. Хорошо созданное приложение не должно зависеть ни от какого конкретного порядка. Если определенный порядок требуется тогда, файлы JAR могут быть перечислены явно в пути к классу.

Расширение подстановочных знаков сделано рано, до вызова основного метода программы, а не поздно, во время самого процесса загрузки класса. Каждый элемент входного пути к классу, содержащего подстановочный знак, заменяется (возможно пустой) последовательность элементов, сгенерированных путем перечисления файлов JAR в именованном каталоге. Например, если каталог foo содержит a.jar, b.jar, и c.jar, то путь к классу foo/* расширен в [1 130], и та строка была бы значением системного свойства java.class.path.

CLASSPATH, переменную среды не рассматривают никто по-другому по сравнению с -classpath (или -cp) параметр командной строки. Таким образом, подстановочные знаки соблюдают во всех этих случаях. Однако подстановочные знаки пути к классу не соблюдают в Class-Path jar-manifest заголовок.

Примечание: из-за известной ошибки в java 8, примеры окон должны использовать обратную косую черту, предшествующую записям с запаздывающей звездочкой: https://bugs.openjdk.java.net/browse/JDK-8131329

1078
ответ дан philwalk 8 June 2017 в 08:47
поделиться

Мы обходим эту проблему путем развертывания основной файл myapp.jar банки, который содержит файл декларации (Manifest.mf), определяющий путь к классу с другими необходимыми банками, которые тогда развертываются вместе с ним. В этом случае только необходимо объявить java -jar myapp.jar при выполнении кода.

Поэтому, если Вы развертываете основное jar в некоторый каталог, и затем помещаете зависимые банки в lib папка под этим, декларация похожа:

Manifest-Version: 1.0
Implementation-Title: myapp
Implementation-Version: 1.0.1
Class-Path: lib/dep1.jar lib/dep2.jar

нбар: это платформенно независимо - мы можем использовать те же банки для запуска на сервере UNIX или в Windows PC.

63
ответ дан bourbert 8 June 2017 в 08:47
поделиться

Единственным путем я знаю, как должен сделать это индивидуально, например:

setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.

Hope, которая помогает!

3
ответ дан om-nom-nom 8 June 2017 в 08:47
поделиться
  • 1
    Главным образом, потому что массив хешей был самой простой вещью, которая могла возможно работать, делая для более ясного примера. Кроме того, и я don' t знают, имеет ли это значение для Вас в Ruby < 1.9, don' хешей; t имеют четко определенный порядок, таким образом, Вы теряете первоначальный заказ строк. – Wayne Conrad 22 January 2010 в 20:16

В Windows это работает:

java -cp "Test.jar;lib/*" my.package.MainClass

и не работает:

java -cp "Test.jar;lib/*.jar" my.package.MainClass

обратите внимание на * .jar, , поэтому подстановочный знак * следует использовать отдельно .


В Linux работает следующее:

java -cp "Test.jar:lib/*" my.package.MainClass

Разделителями являются двоеточия вместо точки с запятой.

221
ответ дан 19 December 2019 в 20:21
поделиться

Для окон требуются кавычки и; должны использоваться как разделитель. например:

java -cp "target\\*;target\\dependency\\*" my.package.Main
4
ответ дан 19 December 2019 в 20:21
поделиться

Вы можете попробовать java -Djava.ext.dirs = jarDirectory http://docs.oracle.com/javase/6/ docs / technotes / guides / extensions / spec.html

Каталог для внешних jar-файлов при запуске java

27
ответ дан 19 December 2019 в 20:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: