Каква е най-добрата практика за включване на jar файлове на трети страни в Java програма?

Имам програма, която се нуждае от няколко библиотеки на трети страни и в момента е пакетирана така:

zerobot.jar (my file)
libs/pircbot.jar
libs/mysql-connector-java-5.1.10-bin.jar
libs/c3p0-0.9.1.2.jar

Доколкото знам, „най-добрият“ начин да се справя с библиотеките на трети страни е да ги поставим в пътеката на класа в манифеста на моя jar файл, който ще работи между платформи, няма да забави стартирането (което групирането им може) и не се натъква на правни проблеми (които преопаковането може да доведе).

Проблемът е за потребители, които сами доставят библиотеките на трети страни (примерен случай на употреба, надстройването им за коригиране на грешка). Две от библиотеките имат номера на версията във файла, което създава проблеми.

Моето текущо решение е, че моята програма има процес на стартиране, който прави нов класов зареждащ инструмент и инстанцира програмата правилно, като го използва. Този персонализиран зареждащ клас добавя всички .jar файлове в lib/ към своя класов път.

Сегашният ми начин работи добре, но сега имам два персонализирани зареждащи класове в моето приложение и скорошна промяна в кода причини проблеми, които са трудни за отстраняване на грешки, така че ако има по-добър начин, бих искал да премахна тази сложност. Също така изглежда като прекомерно инженерство за това, което съм сигурен, че е много често срещана ситуация.

Въпросът ми е как трябва да направя това?


person ZoFreX    schedule 13.03.2010    source източник
comment
@ZoFrex: защо да използвате нов инструмент за зареждане на класове? Защо просто не използвате зареждащия клас по подразбиране, който винаги е URLClassLoader (AFAIK)? По този начин ще имате само един зареждащ клас. Ето как го правя и доставям на стотици машини с OS X и Windows (ако лайното удари вентилатора, бих променил начина, по който го правя;)   -  person SyntaxT3rr0r    schedule 13.03.2010
comment
Всъщност използвам URLClassLoader. Създавам нов, за да инжектирам динамичния classpath, не можете да промените този по подразбиране. Вторият зареждащ клас, който написах по-рано, за плъгин системата.   -  person ZoFreX    schedule 13.03.2010


Отговори (4)


Предоставяме файлове със скриптове с буркана. напр. some.bat, some.sh и т.н.

И от Java6, можете да използвате заместващ знак, за да посочите класове.

Ето една добра статия, която обяснява този подход: https://blogs.oracle.com/mr/entry/class_path_wildcards_in_mustang

person Enno Shioji    schedule 13.03.2010
comment
@Zwei steinen: той иска да бъде междуплатформен. Java 6 означава, че ще се отрежете от огромна част от потребителската база на OS X, която има Mac, които никога официално няма да имат Java 6 (32-битови CPU Mac). - person SyntaxT3rr0r; 13.03.2010
comment
Ехххх за този проект съвместимостта с OS X всъщност не е голям проблем и така или иначе компилирах срещу 1.6. Благодаря за съвета все пак, ще трябва да проверя дали другите ми проекти работят на 1.5! - person ZoFreX; 13.03.2010
comment
Ще посоча classpath в манифеста на jar и ще изисквам крайният потребител да наименува правилно библиотеките на трети страни, когато ги надгражда. Въпреки това отбелязвам това като прието, тъй като имаше най-готината информация. - person ZoFreX; 15.03.2010

Ако аудиторията ви е техническа (и звучи така, ако е готова да пусне нови jar файлове), тогава може би бихте могли да предоставите .sh и .bat файлове, които те могат да редактират, за да променят пътя на класа? Това ще бъде по-прозрачно за тях, отколкото персонализирано зареждане на класове.

person Brian Slesinsky    schedule 14.03.2010
comment
Това не е лош подход, но усложнява нещата, когато актуализират основния програмен буркан, тъй като техните промени ще трябва да бъдат направени отново. Мисля, че като цяло изискването им да преименуват файловете е най-добрият подход, но ако има оплаквания, вероятно ще тръгна по този път. - person ZoFreX; 15.03.2010

Можете да опитате решението Fat-Jar, то работи перфектно с 'Fat Jar Eclipse Plug-In'. Използвал съм за няколко проекта без никакви проблеми. Принципът му изглежда е същият като сегашното ви решение.

person sysoutnull    schedule 13.03.2010
comment
Ако чета правилно, той само обработва опаковката за моята дистрибуция, а не за потребители, надграждащи своите външни библиотеки? - person ZoFreX; 13.03.2010
comment
@bpfurtado: +1, или използвай izpack... Или направи същото сам, не е трудно. - person SyntaxT3rr0r; 13.03.2010
comment
fat-jar е само за опаковане и не предоставя механизъм за надграждане за включените библиотеки. Що се отнася до вашите трудности при дублиране с помощта на персонализиран Classloader, аз просто правя цялата разработка/отстраняване на грешки в моята IDE и след това използвам fat-jar, за да направя внедряването, всички тестове, останали за извършване с „опакованото“ решение, ще бъдат свързани с „ClassNotFoundException“ , това, което никога не се случва, тъй като „fat-jar“ работи доста добре. - person sysoutnull; 14.03.2010
comment
Не съм тествал Fat-Jar, но много методи за преопаковане на всичко в един буркан могат да забавят нещата. Също така си струва да се отбележи, че подобно преопаковане често не е разрешено от лицензите на библиотеки на трети страни, особено ако самото приложение не е под същия лиценз (в моя случай то не е с отворен код). - person ZoFreX; 14.03.2010
comment
Забавете нещата? как? Имате предвид нещо като времето за стартиране на приложението? Защото не виждам това да забавя времето за разработка. Що се отнася до лицензите, ще имате проблема, независимо от техническото решение, което използвате... Мислех, че искате техническо решение. Fat-Jar прави точно това, което се опитахте да направите сами, но е доста стабилен, никога не съм го виждал да се срива и го използвах много. Не е нужно да „преоткривате колелото“, по този начин можете да се съсредоточите върху уникалните функции на вашето приложение ;) - person sysoutnull; 15.03.2010
comment
Имам предвид време за стартиране, а не време за разработка. Някои лицензи позволяват групиране, но не и преопаковане, ако не позволяват групиране, други подходи, изброени тук, ще позволят на крайния потребител да ги пусне сам. Това е чудесно решение за някои ситуации, но не отговаря на основните ми критерии (надграждане). - person ZoFreX; 15.03.2010

Мисля, че ще тръгна по пътя на манифеста. Декларирайте пътя на класа в манифеста за буркана за въвеждане и имайте записи за:

libs/pircbot.jar
libs/mysql-connector-java-5-bin.jar
libs/c3p0.jar

Тогава, ако потребителите искат да надстроят до най-новите версии на библиотеката, те ще трябва да ги преименуват, за да съответстват на това, което е декларирано в манифеста. Не мисля, че това е твърде голяма караница и прави нещата много по-прости вътрешно.

Освен това като цяло не ми харесва идеята за автоматично зареждане на всичко в ./lib/, това изглежда потенциално опасно.

person ZoFreX    schedule 14.03.2010