From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.2.3 (2007-08-08) on sa.int.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-1.1 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.3 Date: Mon, 14 Jan 2008 23:59:16 +0200 From: Igor Vlasenko To: ALT Linux Team development discussions Message-ID: <20080114215916.GA19907@dad.imath.kiev.ua> References: <20080110204106.GA15578@dad.imath.kiev.ua> <20080114070836.GB28583@mw.local.seiros.ru> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20080114070836.GB28583@mw.local.seiros.ru> User-Agent: Mutt/1.4.2.2i Received-SPF: pass (dad.imath.kiev.ua: domain of vlasenko@dad.imath.kiev.ua designates 127.0.0.1 as permitted sender) receiver=dad.imath.kiev.ua; client-ip=127.0.0.1; helo=dad.imath.kiev.ua; envelope-from=vlasenko@dad.imath.kiev.ua; x-software=spfmilter 0.95 http://www.acme.com/software/spfmilter/ with libspf2; Cc: java@altlinux.org Subject: Re: [devel] Java: no magic wand, no magic hammer X-BeenThere: devel@lists.altlinux.org X-Mailman-Version: 2.1.9 Precedence: list Reply-To: ALT Linux Team development discussions List-Id: ALT Linux Team development discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Jan 2008 21:59:30 -0000 Archived-At: List-Archive: List-Post: On Mon, Jan 14, 2008 at 10:08:36AM +0300, Денис Смирнов wrote: DS> On Thu, Jan 10, 2008 at 10:41:06PM +0200, Igor Vlasenko wrote: DS> IV> Java: no magic wand. DS> IV> -------------------- DS> Выводы верны, но не все предпосылки верны. В данном случае в возражениях есть упущения, и поскольку думаю, что такие вопросы будут повторяться, стоит их разобрать детальнее. > IV> 1) стандартные названия библиотек > IV> [никому из нас и в голову не придет собирать libz как > IV> libaltz и пытаться продавливать в апстримы патчи > IV> вида s/-lz/-laltz/ либо паковать Pod::Parser как > IV> Documents::Pod::Parser], не зависящие от названия пакета > IV> (zlib или libz или libaltz, perl или perl-Pod или > IV> perl-PodDocumentUtils) DS> Я правильно понимаю, что если я говорю о Jetty, то я говорю об DS> org.mortbay.*, например? DS> DS> Поясняю мысль -- у Java нет понятия "библиотека". Есть понятие "класс" и DS> "каталоги поиска". Эти каталоги могут быть заzipованы, и тогда это jar. Далее для простоты не будем различать случаи "каталог поиска" и jar, так как различие только в синтаксисе и способе хранения. DS> Но jar не обладает практически никакими свойствами нормальной библиотеки. DS> Хотя по своей сути сильно напоминает старые добрые .a библиотеки. Вот теперь начнем разборку. Возьмем к примеру класс org.viy.Example1 . Q: что будет, если сказать $java org.viy.Example1 ? A: java.lang.NoClassDefFoundError Q: почему? A: не указан -classpath /usr/share/java/viy-example.jar или -classpath /home/viy/example/build . Вот мы и увидели в аргументах вызова папку /home/viy/example/build и архив /usr/share/java/viy-example.jar. Обе сущности и являются хранилищами кода java -- java - библиотеками. Как видим, без указания библиотеки запустить программу не удалось. Q: неправда! я сделал java -classpath /usr/share/java/* org.viy.Example1 и программа нормально отработала без всякого указания библиотек! A: вам везет! org.viy.Example1 лежал только в одном месте - в viy-example.jar и зависимостей у него сложных не было. Попробуйте такой трюк с тем же org.mortbay.jetty, особенно если рядом по зависимостям установлены jetty5 и jetty6. Там несколько библиотек - загрузятся вперемешку и начнут между собой Великую Войну За Тапки. /usr/share/java - это не библиотека, а одно из мест, где библиотеки искать. Было бы нечто вроде /usr/lib, умей java сама искать org.viy.Example1. я считаю аналогию /usr/share/java и /usr/lib обманчивой, точнее будет соответствие /usr/share/java/** и /usr/lib. но пусть будет. Тогда -classpath /usr/share/java/* соответствует линковка ./hello_world cо всеми библиотеками из /usr/lib --- кошмарная противоположность -Wl,--as-needed. Q: и что это доказывает? A: что понятие библиотеки не сводится к понятию класса. Зная все классы, необходимые для запуска приложения, мы тем не менее не сможем слинковать и запустить его, не указав библиотеки, т.е. места, где эти классы находятся. DS> IV> 2) стандартная (мета)информация о зависимостях DS> IV> (выполнена ли она в виде директивы import в питоне DS> IV> либо находится в заголовке ELF binary file) DS> DS> Они самые, import в Java-исходнике. И ссылки на конкретные классы уже в DS> .class. Так что это уже есть. Это зависимости на классы. И они нужны, но из 1) видно, что этого мало, для запуска нужно знать библиотеки (рыбные места :) ) Иногда это одно место, тогда все просто и очевидно. Но в важных достаточно частых случаях их много и так было задумано. DS> Мы здесь имеем слишком тонкую нарезку правда. Единицей у нас является DS> класс/интерфейс, но никак не "библиотека". К счастью у нас единица не DS> "отдельный метод" чему можно сильно радоваться. IMHO, хорошая библиотека экспортирует методов не намного больше, чем jar архив - public классов. DS> Хотя у нас есть еще одна вещь -- в META-INF может быть жестко прописаный DS> classpath. Я не знаю какие недостатки у этого решения, но плюсы очевидны: DS> - можно делать простые файловые зависимости DS> - их удовлетворение может автоматически означать возможность запустить DS> приложение jpackage policy не зря запрещает жестко прописаный в META-INF classpath. см. http://www.freesource.info/wiki/Altlinux/Policy/Java/ClassPathInManifest The Class-Path system of MANIFESTs is evil http://jpackage.org/jpprequest.php https://www.zarb.org/pipermail/jpackage-discuss/2003-June/002095.html Кроме того, добавлю к вышесказанному, что с одной стороны, это аналог -rpath, а стандартных мест, где может быть библиотека, несколько, наподобие /lib и /usr/lib. Посмотрите "Глава 3. Структура директорий" http://www.freesource.info/wiki/Altlinux/Policy/Java/JPackagePolicyTranslation#h11610-10 скрипт build-classpath обходит все эти места, чтобы найти нужную библиотеку. Тот же самый $(build-classpath xml-commons-apis) может развернуться в /usr/share/java/xml-commons-apis.jar, а может в /usr/lib/jvm-exports/jre-1.6.0-sun/xml-commons-apis.jar -> /usr/lib/jvm/java-1.6.0-sun-1.6.0.04/jre/lib/rt.jar Как и в сишных библиотеках, в дистрибутиве -rpath скорее мешает. С другой стороны, и это killer, жестко прописаный в META-INF classpath сделает такие библиотеки непригодными для разработчика. Так бы люди использовали для своих проектов дистрибутивные jar, но с жестко прописаным в META-INF classpath поведение программы с такими библиотеками будет на чужой машине разрушительно непредсказуемым. Кто знает, что и какой версии оно там загрузит, чтобы начать Великую Войну За Тапки ? Придется искать jar'ы по файлопомойкам интернета, откуда угодно, но только не из родного дистрибутива. Кому тогда они вообще нужны? DS> IV> 4) стандартный загрузчик, который используя 2) рекурсивно DS> IV> ищет 1) в 3). DS> Увы. Такой загрузчик даже теоретически можно написать (!), учитывая DS> alternatives. Так я ж в том письме теоретически его и написал :) Хочу только подчеркнуть, что им нужно заканчивать, а ни в коем случае не начинать. Дом строится не с крыши, а с фундамента. Так что no magic wand, no magic hammer. -- Dr. Igor Vlasenko -------------------- Topology Department Institute of Math Kiev, Ukraine