Компиляция Java-библиотек

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

Исходный перечень включал в себя порядка 200 библиотек (перечень см. ниже). Изначально и нам, и заказчику казалось, что эта работа - муторная, но простая. Казалось бы, бери официальные исходники, скачивай их, собирай - и все. Однако в реальности дело оказалось гораздо сложнее.

У нас не было опыта подобной работы именно под Java, поскольку мы больше специализируемся на платформе .Net. Однако задача казалась простой и понятной, поскольку у этих двух технологий много общего (в конце концов, когда-то .Net была скопирована именно с Java, для первой версии даже существовали автоматические конвертеры из одного языка в другой).

Ключевой проблемой оказалось то, что на самом деле авторы библиотек вовсе не следят за тем, чтобы исходные коды в репозитории (в основном в Maven) соответствовали бинарным библиотекам. Из 200 библиотек порядка половины просто не собиралось.

В ряде случаев проблема решалась каким-то простым образом. Скажем, мог быть неправильно прописан путь. Или какая-то простая ошибка в скрипте билда.

Однако часть библиотек оказалась очень крепкими орешками. Проблема усугублялась еще тем, что заказчику не нужны были именно последние версии библиотек (которые все же поддерживаются в более актуальном состоянии), в ряде случаев требовалась определенная «историческая» версия.

Относительно простой проблемой было отсутствие ресурсов. В этом случае мы «разбирали» бинарную версию библиотеки, доставали оттуда нехватающие ресурсы и «подсовывали» их в исходники.

Более серьезной, но тоже решаемой, была проблема файлов классов, расположенных не на своем месте. Мы написали небольшую утилиту, сравнивающую бинарную версию с исходными файлами и показывающую на проблемные места. В ручном режиме мы поместили файлы «куда нужно».

Остальные случаи были хардкорными.

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

Часть библиотек содержало в себе другие библиотеки, причем в виде ресурсов. Иногда на такие «вложенные» библиотеки удавалось найти исходники, иногда нет. Порой получалась целая матрешка: во вложенной библиотеке оказывалась еще одна, ну и так далее...

Имея опыт дизассемблирования в .Net, мы пытались решить проблему подобным образом. Однако тут нас ждало полное разочарование в Java: нам так и не удалось найти нормального декомпилятора. Получившийся код в ряде случаев просто не компилировался обратно. В некоторых случаях ошибки были элементарными (хотя они все равно требовали времени на устранение), а в некоторых - неустранимыми. Например, в некоторых случаях декомпилятор производил два метода с одинаковыми сигнатурами. По опыту .Net мы знаем, что это - один из приемов обфускации, однако в данном случае никаких признаков обфускации не наблюдалось.

Также были случаи т.н. «говнокода». Например, одна общеизвестная библиотека имела некий файл build.xml объемом порядка 1 Кб. Это был скрипт для билда. В нем - адская жесть (иначе не назвать): постоянные подмены имен классов, файлов, включая системные java; обильные goto и прочие «приятности». Мы потратили на сборку этой библиотеки более 3х дней.

Подводя итог, можно сказать, что при первоначальной оценке объема данной работы в 1 человекомесяц мы потратили практически на порядок больше. И квалификация человека, который был бы в состоянии выполнить такой проект, никак не junior, как казалось изначально, а полноценный senior.

Список библиотек, которые нужно было собрать:

1. activation-1.1.jar
2. antlr-2.7.7.jar
3. aopalliance-1.0.jar
4. aopalliance-repackaged-2.4.0-b31.jar
5. asm-5.2.jar
6. aspectjrt-1.8.10.jar
7. aspectjweaver-1.8.10.jar
8. bcprov-jdk15on-1.51.jar
9. castor-1.2.jar
10. catch-exception-1.2.0.jar
11. cglib-nodep-2.2.jar
12. classmate-1.3.0.jar
13. commons-beanutils-1.8.3.jar
14. commons-codec-1.2.jar
15. commons-collections-3.2.1.jar
16. commons-compress-1.0.jar
17. commons-digester-2.1.jar
18. commons-fileupload-1.3.2.jar
19. commons-io-2.4.jar
20. commons-lang-2.6.jar
21. commons-lang3-3.5.jar
22. commons-logging-1.2.jar
23. commons-net-3.4.jar
24. core-3.2.1.jar
25. cxf-core-3.1.6.jar
26. cxf-rt-bindings-soap-3.1.6.jar
27. cxf-rt-bindings-xml-3.1.6.jar
28. cxf-rt-databinding-jaxb-3.1.6.jar
29. cxf-rt-frontend-jaxws-3.1.6.jar
30. cxf-rt-frontend-simple-3.1.6.jar
31. cxf-rt-transports-http-3.1.6.jar
32. cxf-rt-ws-addr-3.1.6.jar
33. cxf-rt-ws-policy-3.1.6.jar
34. cxf-rt-wsdl-3.1.6.jar
35. dom4j-1.6.1.jar
36. dozer-5.5.1.jar
37. ea-agent-loader-1.0.3.jar
38. ehcache-2.10.4.jar
39. ehcache-core-2.5.2.jar
40. ehcache-jgroupsreplication-1.7.jar
41. encoder-1.1.jar
42. fontbox-1.8.8.jar
43. freemarker-2.3.16.jar
44. generic-archiver-1.1.0.jar
45. genson-0.99.jar
46. ghost4j-1.0.1.jar
47. gquery-dnd-bundle-1.0.5.jar
48. gson-2.2.4.jar
49. guava-19.0.jar
50. gwt-log-3.1.6.jar
51. gwt-servlet-2.4.0.jar
52. gwtext-2.0.5.jar
53. hamcrest-core-1.3.jar
54. hibernate-commons-annotations-5.0.1.Final.jar
55. hibernate-core-5.2.9.Final.jar
56. hibernate-ehcache-5.2.9.Final.jar
57. hibernate-jpa-2.1-api-1.0.0.Final.jar
58. hibernate-search-elasticsearch-5.7.0.Final.jar
59. hibernate-search-engine-5.7.0.Final.jar
60. hibernate-search-orm-5.7.0.Final.jar
61. hibernate-validator-5.3.4.Final.jar
62. hk2-api-2.4.0-b31.jar
63. hk2-locator-2.4.0-b31.jar
64. hk2-utils-2.4.0-b31.jar
65. httpasyncclient-4.1.2.jar
66. httpclient-4.5.2.jar
67. httpcore-4.4.4.jar
68. httpcore-nio-4.4.5.jar
69. httpmime-4.5.2.jar
70. icu4j-50.1.1.jar
71. itext-2.1.7.jar
72. itextpdf-5.5.12.jar
73. jackrabbit-text-extractors-1.6.5.jar
74. jackson-annotations-2.1.4.jar
75. jackson-core-2.1.4.jar
76. jackson-core-asl-1.9.2.jar
77. jackson-databind-2.1.4.jar
78. jackson-jaxrs-1.9.2.jar
79. jackson-jaxrs-base-2.5.4.jar
80. jackson-jaxrs-json-provider-2.5.4.jar
81. jackson-mapper-asl-1.9.2.jar
82. jackson-module-jaxb-annotations-2.5.4.jar
83. jackson-xc-1.9.2.jar
84. jai-imageio-core-1.3.1.jar
85. jandex-2.0.3.Final.jar
86. jasperreports-5.6.1.jar
87. jasperreports-fonts-6.0.0.jar
88. jasperserver-dto-6.3.0.jar
89. javase-3.2.1.jar
90. javassist-3.20.0-GA.jar
91. javax.annotation-api-1.2.jar
92. javax.inject-2.4.0-b31.jar
93. javax.mail-1.5.1.jar
94. javax.ws.rs-api-2.0.1.jar
95. jaxb-core-2.2.11.jar
96. jaxb-impl-2.2.11.jar
97. jboss-logging-3.3.0.Final.jar
98. jboss-transaction-api_1.2_spec-1.0.1.Final.jar
99. jboss-vfs-3.2.12.Final.jar
100. jcifs-1.3.17.jar
101. jcl-core-2.8.jar
102. jcl-over-slf4j-1.7.25.jar
103. jcommander-1.48.jar
104. jcommon-1.0.15.jar
105. jempbox-1.8.8.jar
106. jersey-client-2.22.1.jar
107. jersey-common-2.22.1.jar
108. jersey-core-1.19.jar
109. jersey-entity-filtering-2.22.1.jar
110. jersey-guava-2.22.1.jar
111. jersey-json-1.19.jar
112. jersey-media-jaxb-2.22.1.jar
113. jersey-media-json-jackson-2.22.1.jar
114. jersey-multipart-1.19.jar
115. jest-2.0.4.jar
116. jest-common-2.0.4.jar
117. jettison-1.1.jar
118. jfreechart-1.0.12.jar
119. jgroups-4.0.2.Final.jar
120. jmyspell-core-1.0.0-beta-2.jar
121. jna-4.1.0.jar
122. jna-platform-4.2.1.jar
123. jodconverter-2.2.2.jar
124. jodconverter-core-3.0-beta-4.jar
125. jrs-rest-java-client-6.3.0.jar
126. json-20160810.jar
127. jsr181-api-1.0-MR1.jar
128. jsr250-api-1.0.jar
129. jsr305-2.0.3.jar
130. jsr311-api-1.1.1.jar
131. jstl-1.2.jar
132. jtds-1.3.1.jar
133. juh-3.2.1.jar
134. jul-to-slf4j-1.7.25.jar
135. junit-4.11.jar
136. jurt-3.2.1.jar
137. lept4j-1.4.0.jar
138. log4j-1.2.17.jar
139. lucene-analyzers-common-5.5.4.jar
140. lucene-analyzers-smartcn-5.5.4.jar
141. lucene-backward-codecs-5.5.4.jar
142. lucene-core-5.5.4.jar
143. lucene-facet-5.5.4.jar
144. lucene-highlighter-5.5.4.jar
145. lucene-join-5.5.4.jar
146. lucene-memory-5.5.4.jar
147. lucene-misc-5.5.4.jar
148. lucene-queries-5.5.4.jar
149. lucene-queryparser-5.5.4.jar
150. lucene-sandbox-5.5.4.jar
151. lucene-suggest-5.5.4.jar
152. mail-1.4.7.jar
153. mimepull-1.9.3.jar
154. mockito-core-1.9.5.jar
155. neethi-3.0.3.jar
156. nekohtml-1.9.7.jar
157. object-cloner-0.1.jar
158. objenesis-2.1.jar
159. olap4j-JS-4.jar
160. opencsv-3.4.jar
161. osgi-resource-locator-1.0.1.jar
162. pdfbox-1.8.8.jar
163. poi-3.9.jar
164. poi-scratchpad-3.9.jar
165. pyramidio-1.1.0.jar
166. quality-check-1.3.jar
167. reflections-0.9.9-RC1.jar
168. ridl-3.2.1.jar
169. sigar-1.6.5.132.jar
170. slf4j-api-1.7.25.jar
171. slf4j-log4j12-1.7.22.jar
172. spring-aop-4.2.2.RELEASE.jar
173. spring-beans-4.2.2.RELEASE.jar
174. spring-context-4.2.2.RELEASE.jar
175. spring-context-support-4.2.2.RELEASE.jar
176. spring-core-4.2.2.RELEASE.jar
177. spring-expression-4.2.2.RELEASE.jar
178. spring-jdbc-4.2.2.RELEASE.jar
179. spring-ldap-core-2.0.2.RELEASE.jar
180. spring-orm-4.2.2.RELEASE.jar
181. spring-security-config-4.0.3.RELEASE.jar
182. spring-security-core-4.0.3.RELEASE.jar
183. spring-security-ldap-4.0.3.RELEASE.jar
184. spring-security-web-4.0.3.RELEASE.jar
185. spring-tx-4.2.2.RELEASE.jar
186. spring-web-4.2.2.RELEASE.jar
187. spring-webmvc-4.2.2.RELEASE.jar
188. spring4gwt-0.0.1.jar
189. stax-api-1.0-2.jar
190. stax2-api-3.1.4.jar
191. tess4j-3.4.0.jar
192. truezip-6.8.2.jar
193. uadetector-core-0.9.16.jar
194. uadetector-resources-2014.04.jar
195. unoil-3.2.1.jar
196. validation-api-1.1.0.Final.jar
197. waffle-jna-1.8.1.jar
198. waffle-spring-security3-1.8.1.jar
199. woodstox-core-asl-4.4.1.jar
200. wsdl4j-1.6.3.jar
201. xercesImpl-2.8.1.jar
202. xml-apis-1.3.02.jar
203. xml-resolver-1.2.jar
204. xmlgraphics-commons-1.4.jar
205. xmlschema-core-2.2.1.jar
206. xmlsec-2.0.8.jar