ALT Linux Team development discussions
 help / color / mirror / Atom feed
* [devel] java dependencies
@ 2007-06-08 15:39 Alexey Tourbin
  2007-06-08 17:25 ` Igor Vlasenko
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Alexey Tourbin @ 2007-06-08 15:39 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 5429 bytes --]

Я переделал rpm-build-java (см. /people/at/packages/rpm-build-java.git).
Статус экспериментальный и недоделанный (подразумевает новый rpm-build,
которого пока нет в сизифе), но основные моменты продуманы.

Вкратце, я предлагаю реализовать поиск зависимостей на основе точной
информации из *.class файлов, и примерно с такой же гранулярностью (на уровне
*.class файлов, см. ниже насчет вложенных классов).  Также можно сохранить
Provides зависимости на уровне *.jar файлов (для совместимости с JPackage),
но все Requires зависимости я предлагаю перевести на уровень *.class файлов.

(Для тех, кто совсем не в курсе, поясню, что *.jar файлы -- это zip-архивы,
которые содержат в себе много-много class-файлов -- байткод.  Java умеет
смотреть в *.jar архивы как в обычные каталоги и отыскивать там class-файлы.
Но все реальные зависимости имеют место быть между class-файлами, а не
jar-архивами.  Дальше можно не читать.)

Предлагаемый формат зависимостей имеет вид java(java.lang.Object).

Я пока не во всём разобрался, поэтому ищу специалистов по java (особенно по JVM).

Я прочитал спецификацию "VM Spec: The class File Format"
http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html
и буквально по этой спецификации написал на перле парсер class-файлов, который
в первом приближении умеет извлекать зависимости.  Похожий парсер есть в
rpm/tools/javadeps.c, но мой парсер получился в несколько раз короче и проще,
так что написание с нуля я не считаю убитым временем.

Парсер называется jcf-reqprov (java class file, по аналогии с jcf-dump из gcc)
и умеет полностью парсить константный пул и таблицу классов (см. VM Spec).
Предыдущий предельно упрощенный парсер из java.req (egrep -hao 'L[a-zA-Z/_]+;')
делал совсем не то что нужно, хотя и выдавал какие-то зависимости.

Следующий вопрос адресован специалистам по JVM.  Хотелось бы не просто парсить
константный пул и таблицу классов, а дополнить парсер семантикой зависимостей,
чтобы можно было сказать, в чем именно состоит зависимость на некоторый класc
(например, суперкласс, суперинтерфейс и т.п.).  Поддержка семантики
зависимостей в первом приближении мной уже продумана, но пока как следует не
работает.  Мне хотелось бы знать, в каких именно случаях JVM ЗАГРУЖАЕТ другой
class-файл, когда видит на него ссылку.  Например, если некоторый метод умеет
брать аргумент с типом некоторого другого объекта:
	ThisClass.Method(arg=OtherClass)
означает ли это, что JVM сразу же, в процессе начальной обработки
(компиляции) ThisClass, будет также (физически) загружать и OtherClass?
Или же загрузка OtherClass в некотором смысле откладывается, то есть,
например, происходит по факту вызова ThisClass.Method(arg) откуда-то ещё?

Другими словами, семантика зависимостей нужна для того, чтобы отделить существенные
зависимости, без которых точно нельзя обойтись при начальной загрузке данного
class-файла, от вторичных зависимостей, загрузка которых, возможно, является
необязательной, т.е. они сами по себе загружаются откуда-то ещё.  Этим я пытаюсь
сказать, что в rpm-зависимостях у rpm-пакета нужно писать только реально
необходимые классы, а не просто все имена классов, которые удается извлечь
неким нехитрым способом (с помощью dumb парсера).

Перехожу к техническим подробностям.  Я также переделал java.req и сделал
комплементарный java.prov.  Первый положительный результат: поиск Requires
зависимостей в пакете j2se1.5-sun-1.5.0.11-alt4 дал нулевой результат -- все
Requires взаимно уничтожаются с Provides, т.е. зависимости замкнуты.

Несколько менее положительным результатом следует считать размер as-is Provides
зависимостей у этого же пакета -- около 440K (всего около 10000 классов).  При
этом уже используется одна довольно сильная оптимизация -- исключение т.н.
private классов (см. VM Spec).  Впрочем, использование ещё двух эвристических
оптимизаций (хаков) позволило уменьшить список Provides до 120K (всего около
3000 классов в Provides), что уже более приемлемо, хотя и на грани.

Сгруппируем список as-is provides пакета j2se1.5-sun по префиксам:

$ cut -d. -f-2 prov |sort |uniq -c |sort -n |tail
    207 java(java.util
    215 java(sun.text
    258 java(sun.nio
    322 java(sun.awt
    327 java(sun.io
    385 java(java.awt
    399 java(sun.security
    536 java(org.omg
    851 java(javax.swing
   3456 java(com.sun
$

Отсюда видно, что первая эвристическая оптимизация списка provides должна
состоять в том, чтобы исключить (взаимно уничтожить) зависимости вида
java(com.sun.*) и java(sun.*).  Такие зависимости, по идее, относятся к
особенностям реализации и не должны выходить за рамки этой реализации.

Другая менее очевидная оптимизация, которая позволяет сократить размер
зависимостей ещё примерно на 20%, состоит во взаимном уничтожении зависимостей
"с долларом".  Зависимости типа java(Class$Subclass) появляются, когда файл
Class логически содержит в себе вложенный (полностью объявленный и
реализованный) класс Subclass.  В таком случае зависимость на Class$Subclass
должна полностью сводиться на Class.  Эта оптимизация несколько ухудшает
гранулярность зависимостей, особенно с учетом того, что в java нет средств
версионирования классов.  Однако избавление от bloat (излишнего груза)
представляется скорее привлекательным.  Зависимости "с долларом" кажутся
всё же не слишком органичными (ну, не очень красивыми) для rpm-пакетов.

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [devel] java dependencies
  2007-06-08 15:39 [devel] java dependencies Alexey Tourbin
@ 2007-06-08 17:25 ` Igor Vlasenko
  2007-06-08 23:51 ` Alexey Rusakov
  2007-06-09 10:47 ` Igor Vlasenko
  2 siblings, 0 replies; 5+ messages in thread
From: Igor Vlasenko @ 2007-06-08 17:25 UTC (permalink / raw)
  To: ALT Devel discussion list

On Fri, Jun 08, 2007 at 07:39:03PM +0400, Alexey Tourbin wrote:
> Я переделал rpm-build-java (см. /people/at/packages/rpm-build-java.git).
> Статус экспериментальный и недоделанный (подразумевает новый rpm-build,
> которого пока нет в сизифе), но основные моменты продуманы.

Есть замечание из жизненной практики. 
Вначале меня эта идея воодушевила, 
но набравшись некоторого опыта в упаковке java пакетов и набегавшись 
при этом по граблям, хочу обратить внимание на следующую проблему.

зависимости на классы принципиально не достаточны, так как
программа не знает, где хранятся эти классы.

просто загружать все классы нельзя, хотя бы поскольку памяти не хватит.
классы хранятся в jar'ах, и программе нужно знать имя jar'а.
канонических имен нет, лучшее что есть --- россыпь симлинков
и набор альтернатив для интерфейсов.

Т.е. если rpm по зависимостям и дотянет нужный пакет, автоматически 
он не подхватится и все равно его jar нужно будет подтягивать вручную.
Поэтому автоматический поиск зависимостей несколько тавтологичен,
так его все равно надо вручную дублировать.

В этом основное отличие от других языков: там это существенное облегчение 
жизни, здесь --- не более чем средство контроля, при чем недостаточное.

а rpmdb оно будет раздувать чудовищно.

> Вкратце, я предлагаю реализовать поиск зависимостей на основе точной
> информации из *.class файлов, и примерно с такой же гранулярностью (на уровне
> *.class файлов, см. ниже насчет вложенных классов).  Также можно сохранить
> Provides зависимости на уровне *.jar файлов (для совместимости с JPackage),
> но все Requires зависимости я предлагаю перевести на уровень *.class файлов.
> 
> (Для тех, кто совсем не в курсе, поясню, что *.jar файлы -- это zip-архивы,
> которые содержат в себе много-много class-файлов -- байткод.  Java умеет
> смотреть в *.jar архивы как в обычные каталоги и отыскивать там class-файлы.
> Но все реальные зависимости имеют место быть между class-файлами, а не
> jar-архивами.  Дальше можно не читать.)
> 
> Предлагаемый формат зависимостей имеет вид java(java.lang.Object).
> 
> Я пока не во всём разобрался, поэтому ищу специалистов по java (особенно по JVM).
> 
> Я прочитал спецификацию "VM Spec: The class File Format"
> http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html
> и буквально по этой спецификации написал на перле парсер class-файлов, который
> в первом приближении умеет извлекать зависимости.  Похожий парсер есть в
> rpm/tools/javadeps.c, но мой парсер получился в несколько раз короче и проще,
> так что написание с нуля я не считаю убитым временем.
> 
> Парсер называется jcf-reqprov (java class file, по аналогии с jcf-dump из gcc)
> и умеет полностью парсить константный пул и таблицу классов (см. VM Spec).
> Предыдущий предельно упрощенный парсер из java.req (egrep -hao 'L[a-zA-Z/_]+;')
> делал совсем не то что нужно, хотя и выдавал какие-то зависимости.
> 
> Следующий вопрос адресован специалистам по JVM.  Хотелось бы не просто парсить
> константный пул и таблицу классов, а дополнить парсер семантикой зависимостей,
> чтобы можно было сказать, в чем именно состоит зависимость на некоторый класc
> (например, суперкласс, суперинтерфейс и т.п.).  Поддержка семантики
> зависимостей в первом приближении мной уже продумана, но пока как следует не
> работает.  Мне хотелось бы знать, в каких именно случаях JVM ЗАГРУЖАЕТ другой
> class-файл, когда видит на него ссылку.  Например, если некоторый метод умеет
> брать аргумент с типом некоторого другого объекта:
> 	ThisClass.Method(arg=OtherClass)
> означает ли это, что JVM сразу же, в процессе начальной обработки
> (компиляции) ThisClass, будет также (физически) загружать и OtherClass?
> Или же загрузка OtherClass в некотором смысле откладывается, то есть,
> например, происходит по факту вызова ThisClass.Method(arg) откуда-то ещё?
> 
> Другими словами, семантика зависимостей нужна для того, чтобы отделить существенные
> зависимости, без которых точно нельзя обойтись при начальной загрузке данного
> class-файла, от вторичных зависимостей, загрузка которых, возможно, является
> необязательной, т.е. они сами по себе загружаются откуда-то ещё.  Этим я пытаюсь
> сказать, что в rpm-зависимостях у rpm-пакета нужно писать только реально
> необходимые классы, а не просто все имена классов, которые удается извлечь
> неким нехитрым способом (с помощью dumb парсера).
> 
> Перехожу к техническим подробностям.  Я также переделал java.req и сделал
> комплементарный java.prov.  Первый положительный результат: поиск Requires
> зависимостей в пакете j2se1.5-sun-1.5.0.11-alt4 дал нулевой результат -- все
> Requires взаимно уничтожаются с Provides, т.е. зависимости замкнуты.
> 
> Несколько менее положительным результатом следует считать размер as-is Provides
> зависимостей у этого же пакета -- около 440K (всего около 10000 классов).  При
> этом уже используется одна довольно сильная оптимизация -- исключение т.н.
> private классов (см. VM Spec).  Впрочем, использование ещё двух эвристических
> оптимизаций (хаков) позволило уменьшить список Provides до 120K (всего около
> 3000 классов в Provides), что уже более приемлемо, хотя и на грани.
> 
> Сгруппируем список as-is provides пакета j2se1.5-sun по префиксам:
> 
> $ cut -d. -f-2 prov |sort |uniq -c |sort -n |tail
>     207 java(java.util
>     215 java(sun.text
>     258 java(sun.nio
>     322 java(sun.awt
>     327 java(sun.io
>     385 java(java.awt
>     399 java(sun.security
>     536 java(org.omg
>     851 java(javax.swing
>    3456 java(com.sun
> $
> 
> Отсюда видно, что первая эвристическая оптимизация списка provides должна
> состоять в том, чтобы исключить (взаимно уничтожить) зависимости вида
> java(com.sun.*) и java(sun.*).  Такие зависимости, по идее, относятся к
> особенностям реализации и не должны выходить за рамки этой реализации.
> 
> Другая менее очевидная оптимизация, которая позволяет сократить размер
> зависимостей ещё примерно на 20%, состоит во взаимном уничтожении зависимостей
> "с долларом".  Зависимости типа java(Class$Subclass) появляются, когда файл
> Class логически содержит в себе вложенный (полностью объявленный и
> реализованный) класс Subclass.  В таком случае зависимость на Class$Subclass
> должна полностью сводиться на Class.  Эта оптимизация несколько ухудшает
> гранулярность зависимостей, особенно с учетом того, что в java нет средств
> версионирования классов.  Однако избавление от bloat (излишнего груза)
> представляется скорее привлекательным.  Зависимости "с долларом" кажутся
> всё же не слишком органичными (ну, не очень красивыми) для rpm-пакетов.



> _______________________________________________
> Devel mailing list
> Devel@lists.altlinux.org
> https://lists.altlinux.org/mailman/listinfo/devel

-- 

Dr. Igor Vlasenko
--------------------
Topology Department
Institute of Math
Kiev, Ukraine



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [devel] java dependencies
  2007-06-08 15:39 [devel] java dependencies Alexey Tourbin
  2007-06-08 17:25 ` Igor Vlasenko
@ 2007-06-08 23:51 ` Alexey Rusakov
  2007-06-09 10:47 ` Igor Vlasenko
  2 siblings, 0 replies; 5+ messages in thread
From: Alexey Rusakov @ 2007-06-08 23:51 UTC (permalink / raw)
  To: devel

On Fri, 8 Jun 2007 19:39:03 +0400
Alexey Tourbin wrote:

> Я переделал rpm-build-java (см. /people/at/packages/rpm-build-java.git).
> Статус экспериментальный и недоделанный (подразумевает новый rpm-build,
> которого пока нет в сизифе), но основные моменты продуманы.
> 
> Вкратце, я предлагаю реализовать поиск зависимостей на основе точной
> информации из *.class файлов, и примерно с такой же гранулярностью (на уровне
> *.class файлов, см. ниже насчет вложенных классов).  Также можно сохранить
> Provides зависимости на уровне *.jar файлов (для совместимости с JPackage),
> но все Requires зависимости я предлагаю перевести на уровень *.class файлов.
> 
> (Для тех, кто совсем не в курсе, поясню, что *.jar файлы -- это zip-архивы,
> которые содержат в себе много-много class-файлов -- байткод.  Java умеет
> смотреть в *.jar архивы как в обычные каталоги и отыскивать там class-файлы.
> Но все реальные зависимости имеют место быть между class-файлами, а не
> jar-архивами.  Дальше можно не читать.)
> 
> Предлагаемый формат зависимостей имеет вид java(java.lang.Object).
> 
> Я пока не во всём разобрался, поэтому ищу специалистов по java (особенно по JVM).
> 
> Я прочитал спецификацию "VM Spec: The class File Format"
> http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html
> и буквально по этой спецификации написал на перле парсер class-файлов, который
> в первом приближении умеет извлекать зависимости.  Похожий парсер есть в
> rpm/tools/javadeps.c, но мой парсер получился в несколько раз короче и проще,
> так что написание с нуля я не считаю убитым временем.
> 
> Парсер называется jcf-reqprov (java class file, по аналогии с jcf-dump из gcc)
> и умеет полностью парсить константный пул и таблицу классов (см. VM Spec).
> Предыдущий предельно упрощенный парсер из java.req (egrep -hao 'L[a-zA-Z/_]+;')
> делал совсем не то что нужно, хотя и выдавал какие-то зависимости.
> 
> Следующий вопрос адресован специалистам по JVM.  Хотелось бы не просто парсить
> константный пул и таблицу классов, а дополнить парсер семантикой зависимостей,
> чтобы можно было сказать, в чем именно состоит зависимость на некоторый класc
> (например, суперкласс, суперинтерфейс и т.п.).  Поддержка семантики
> зависимостей в первом приближении мной уже продумана, но пока как следует не
> работает.  Мне хотелось бы знать, в каких именно случаях JVM ЗАГРУЖАЕТ другой
> class-файл, когда видит на него ссылку.  Например, если некоторый метод умеет
> брать аргумент с типом некоторого другого объекта:
> 	ThisClass.Method(arg=OtherClass)
> означает ли это, что JVM сразу же, в процессе начальной обработки
> (компиляции) ThisClass, будет также (физически) загружать и OtherClass?
> Или же загрузка OtherClass в некотором смысле откладывается, то есть,
> например, происходит по факту вызова ThisClass.Method(arg) откуда-то ещё?
Насколько я ничего не понимаю в JVM, загрузка класса происходит
непосредственно перед использованием его имени в программе (то есть не
при начальной обработке точно). Но есть одно "но": существуют Just-in-Time,
и, хуже того, Ahead-of-Time компиляторы, которые на это поведение могут
существенно повлиять, в частности, поднимая какие-то классы раньше
времени.
Но честно говоря, мне сама идея описания зависимостей в терминах
классов видится неудачной; это не слишком отличается от описания
зависимостей между библиотеками на C в терминах конкретных
предоставляемых/используемых функций. Далеко не все публичные классы на
самом деле рассчитаны на использование снаружи - это мог быть где-то
недогляд программиста, а где-то класс оставили публичным просто "на всякий
случай, вдруг кому пригодится". И перечислять все классы в зависимостях
rpm, имхо, неразумно. Уж лучше изобрести некую концепцию, сходную с
версионированием динамических библиотек.

-- 
  Alexey "Ktirf" Rusakov
  GNOME Project
  ALT Linux Team


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [devel] java dependencies
  2007-06-08 15:39 [devel] java dependencies Alexey Tourbin
  2007-06-08 17:25 ` Igor Vlasenko
  2007-06-08 23:51 ` Alexey Rusakov
@ 2007-06-09 10:47 ` Igor Vlasenko
  2007-06-09 10:54   ` Epiphanov Sergei
  2 siblings, 1 reply; 5+ messages in thread
From: Igor Vlasenko @ 2007-06-09 10:47 UTC (permalink / raw)
  To: ALT Devel discussion list

Есть предложение:
Если бы этот код вынести в qa-robot...
Были бы одни достоинства (качественный контроль)
и никаких недостатков (сверхдутые requires/provides)


-- 

Dr. Igor Vlasenko
--------------------
Topology Department
Institute of Math
Kiev, Ukraine



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [devel] java dependencies
  2007-06-09 10:47 ` Igor Vlasenko
@ 2007-06-09 10:54   ` Epiphanov Sergei
  0 siblings, 0 replies; 5+ messages in thread
From: Epiphanov Sergei @ 2007-06-09 10:54 UTC (permalink / raw)
  To: ALT Devel discussion list

В сообщении от Saturday 09 June 2007 14:47:33 Igor Vlasenko написал(а):
> Есть предложение:
> Если бы этот код вынести в qa-robot...
> Были бы одни достоинства (качественный контроль)
> и никаких недостатков (сверхдутые requires/provides)

Тогда следующим и последним его сообщением будет "жаба задушила". :D

-- 
С уважением, Епифанов Сергей

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-06-09 10:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-06-08 15:39 [devel] java dependencies Alexey Tourbin
2007-06-08 17:25 ` Igor Vlasenko
2007-06-08 23:51 ` Alexey Rusakov
2007-06-09 10:47 ` Igor Vlasenko
2007-06-09 10:54   ` Epiphanov Sergei

ALT Linux Team development discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \
		devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru
	public-inbox-index devel

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://lore.altlinux.org/org.altlinux.lists.devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git