2016-10-31 8 views
3

Я пытаюсь перенести проект Maven в Bazel и испытывая проблемы с улучшением Datanucleus.Улучшение Datanucleus с Bazel

После jar -файл построен, Datanucleus просматривает его и выполняет некоторые манипуляции с байт-кодом для улучшения устойчивых классов. Способ выполнения этого в Bazel заключается в определении правила, которое принимает вывод *.jar вывода java_library и создает новую улучшенную версию библиотеки.

Проблема, которая у меня есть, заключается в том, что для моего правила мне нужен datanucleus-core пакет из внешних библиотек. При попытке доступа к нему из genrule по $(location //third_party:datanucleus_core) она указывала на банку, который не имеет никаких классов:

(genrule) cmd = "echo $(location //third_party:datanucleus_core)" 
bazel-out/local-fastbuild/bin/third_party/liborg_datanucleus_datanucleus_core.jar 

(genrule) cmd = "jar tf $(location //third_party:datanucleus_core)" 
META-INF/ 
META-INF/MANIFEST.MF 

jar -file разрешаться Базеле в genrule из $(location //third_party:datanucleus_core) содержит только META-INF/MANIFEST.MF со следующим содержанием:

Manifest-Version: 1.0 
Created-By: blaze 

Я попытался использовать правило java_binary, которое добавляет правильный путь datanucleus_core.jar в путь к классам, но Datanucleus расширяет мою библиотеку на месте и не может записать свои изменения на диске (переписать входной файл правила). Также правило java_binary не должно использоваться для строительства.

Итак, вопрос в том, что является лучшим способом для повышения библиотеки jar в Bazel, использующей утилиту Datanucleus, которая предоставляется в качестве сторонней зависимости в репозитории Maven?

Базэл строить этикетки: 0.3.2-homebrew, ОС: OS X El Capitan (10.11.6), Java: 1.8.0_92

Update

объявления зависимостей DataNucleus:

# WORKSPACE 
maven_jar(
    name = "org_datanucleus_datanucleus_core", 
    artifact = "org.datanucleus:datanucleus-core:5.0.3", 
) 

# third_party/BUILD 
java_library(
    name = "org_datanucleus_datanucleus_core", 
    visibility = ["//visibility:public"], 
    exports = ["@org_datanucleus_datanucleus_core//jar"], 
) 

(на мой вопрос, который я укоротить org_datanucleus_datanucleus_core к datanucleus_core)

+1

Никакой процесс улучшения не улучшит классы * IN A JAR *. Если это то, что вы делаете ... Вам нужно распаковать, улучшить, упаковать их. –

ответ

3

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

  1. Создать банку.
  2. Уничтожьте файлы классов.
  3. Запустите усовершенствования.
  4. Jar it back up.

Шагов 2 & 3 должны быть свернуты в 4, так как Базэл настаивает, что вы объявляете все входы & выходы правила сборки (и вы не можете знать, что .class файлов .java файл будет генерировать, так Базэл всегда поднимает их).

Создать datanucleus.bzl файл, чтобы объявить ваше правило улучшающего в Оно должно выглядеть примерно так:.

# Run datastore enhancements on the java_library named "jarname". 
def enhance(jarname): 
    # src is the name of the jar file your java_library rule generates. 
    src = "lib" + jarname + ".jar" 
    native.genrule(
     name = jarname + "-enhancement", 
     srcs = [ 
      src, 
      "//third_party:datanucleus_core" 
     ], 
     outs = [jarname + "-enhanced.jar"], 
     cmd = """ 
# Un-jar the .class files. 
jar tf $(location {0}) 
# Run the enhance. 
classes="" 
for $$class in $$(find . -name *.class); do 
    java -cp {0}:$(location //third_party:datanucleus_core) $$class 
    classes="$$classes $$class" 
done 
# jar them back up. 
jar cf [email protected] $$classes""".format(src), 
) 

(я не слишком хорошо знаком с датастором так cmd может потребоваться некоторое изменение, но оно должно быть, Главная идея.)

Затем в файле BUILD, вы могли бы сделать:

java_library(
    name = "my-lib", 
    srcs = glob(["*.java"]), 
    deps = ["..."], 
) 

# import the rule you wrote. 
load('//:datanucleus.bzl', 'enhance') 
enhance("my-lib") 

Теперь вы можете сделать:

bazel build //:my-lib-enhanced.jar 

и использовать my-lib-enhanced.jar как зависимость в других java_ правил.

Дополнительная информация о .bzl файлах: https://bazel.build/versions/master/docs/skylark/concepts.html.


Edited добавить больше информации в зависимости от баночки:

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

 srcs = [ 
      src, 
      "@datanucleus_core//jar" 
     ], 

Это даст вам реальную банку.

Если по какой-то причине вам нужно банку, чтобы быть в THIRD_PARTY, вы можете изменить THIRD_PARTY/BUILD создать Deploy банку, который представляет собой Java двоичный файл, который связывает всю его зависимостей для развертывания (поскольку вы «повторно на самом деле не собираюсь использовать его в качестве двоичного файла, вы можете использовать все, что вы хотите для основного имени класса):

java_binary(
    name = "datanucleus-core", 
    main_class = "whatever", 
    runtime_deps = ["@org_datanucleus_datanucleus_core//jar"], 
) 

genrule(
    name = "your-lib", 
    srcs = [":datanucleus-core_deploy.jar", ...], 
) 

:datanucleus-core_deploy.jar называется неявными целевым: он построен только по желанию, но могут быть сгенерированы из вашего объявления java_binary.

+0

Благодарим вас за подробный ответ @kristina. Это действительно полезно. Есть только одна вещь, о которой я беспокоюсь. Как я уже упоминал в своем вопросе, у меня возникают проблемы с доступом к сторонней «банке» из «genrule». Файл 'jar', возвращенный из' $ (location // third_party: datanucleus_core) ', не содержит классов, поэтому добавление его в classpath, как в вашем примере, не сработает. Он содержит только «МАНИФЕСТ.МФ», который говорит, что он был «Создан: от: пламени». Есть ли у вас какие-либо идеи, почему это происходит и как я могу это исправить? Я обновил сообщение с моими заявлениями о зависимости Datanucleus. – FireFry

+0

Я обновил свой ответ, чтобы включить информацию о том, как получить банку в вашем пути к классам. Цели библиотеки Java отслеживают свои зависимости, но они не упаковывают их (как вы видели). В противном случае банки увеличивались бы и увеличивались по мере увеличения вашего дерева сборки, поэтому они не включаются до тех пор, пока они не понадобятся, например, в бинарном развертывании. – kristina

+0

Отлично! Большое спасибо, Кристина! – FireFry

 Смежные вопросы

  • Нет связанных вопросов^_^