datanucleus


Datanucleus enhancement with Bazel


I'm trying to migrate Maven project to Bazel and having troubles with Datanucleus enhancement.
After jar-file is build, Datanucleus looks inside it and does some byte-code manipulation to enhance persistable classes. The way to perform this in Bazel is by defining a rule that takes the *.jar output of java_library rule and creates a new enhanced version of the library.
The problem that I have is that for my rule I need datanucleus-core package from external libraries. When I try to access it from a genrule by $(location //third_party:datanucleus_core) it point to a jar which has no classes:
(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
The jar-file resolved by Bazel in genrule from $(location //third_party:datanucleus_core) contains only META-INF/MANIFEST.MF with the following content:
Manifest-Version: 1.0
Created-By: blaze
I tried to use java_binary rule that adds a correct datanucleus_core.jar into classpath, but Datanucleus enhances my libary in-place and fails to write its changes on disk (rewrite the rule's input file). Also java_binary rule is not supposed to be used for building.
So the question is what is the best way to enhance jar library in Bazel running Datanucleus utility, which is provided as a third-party dependency in Maven repository?
Bazel build label: 0.3.2-homebrew, OS: OS X El Capitan (10.11.6), java: 1.8.0_92
Update
Datanucleus dependency declaration:
# 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"],
)
(in my question I shortened org_datanucleus_datanucleus_core to datanucleus_core)
As Neil Stockton mentioned, you cannot enhance classes in a jar. So, the basic strategy will be:
Create the jar.
Unjar the class files.
Run the enhancements.
Jar it back up.
Steps 2 & 3 have to be rolled into 4, as Bazel insists that you declare all inputs & outputs to a build rule (and you cannot know what .class files a .java file will generate, so Bazel always jars them up).
Create a datanucleus.bzl file to declare your enhancement rule in. It should look something like:
# 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 $# $$classes""".format(src),
)
(I'm not too familiar with datastore so the cmd might need some modification, but it should be that general idea.)
Then, in your BUILD file, you'd do:
java_library(
name = "my-lib",
srcs = glob(["*.java"]),
deps = ["..."],
)
# import the rule you wrote.
load('//:datanucleus.bzl', 'enhance')
enhance("my-lib")
Now you can do:
bazel build //:my-lib-enhanced.jar
and use my-lib-enhanced.jar as a dependency in other java_ rules.
More info on .bzl files: https://bazel.build/versions/master/docs/skylark/concepts.html.
Edited to add more info on depending on a jar:
There are a couple of options to get a jar that contains the content of datanucleus. First, you don't need the layer of indirection: you can just say:
srcs = [
src,
"#datanucleus_core//jar"
],
This will give you the actual jar.
If, for some reason, you need the jar to be in third_party, you can modify third_party/BUILD to create a deploy jar, which is a java binary that bundles up all of its dependencies for deployment (since you're not actually going to using it as a binary, you can use whatever you want for the main class name):
java_binary(
name = "datanucleus-core",
main_class = "whatever",
runtime_deps = ["#org_datanucleus_datanucleus_core//jar"],
)
genrule(
name = "your-lib",
srcs = [":datanucleus-core_deploy.jar", ...],
)
The :datanucleus-core_deploy.jar is called an implicit target: it's only built if requested, but it can be generated from your java_binary declaration.

Related Links

How to load entity with its 1 to 1 relation in DataNucleus, using native SQL query with JOINS
How to fetch related object using JDOQL named query?
Datanucleus enhancement with Bazel
DN 4.0.x and oracle : java.util.Date mapped to wrong rdbms type
Is ReferentialJDOStateManager not used in DataNucleus 4.x?
DataNucleus JDO primary key with enum
How to create a Datanucleus JPA 2.x query with CriteriaQuery that is based on values from an embedded map
How do I replace Hibernate with DataNucleus JPA in a JHipster project?
getting this error while enhancing using Datanucleus. any idea
Weird “com.vividsolutions.jts.geom.Geometry” ClassNotResolvedException exception
Does DataNucleus persist JodaTime's DateTime differently with a non-local timezone?
Bulk update with datanucleus errors out
Detailed and clear specification for datanucleus jdo extensions?
Unique constraint with DataNucleus discriminator based multitenancy
Datanucleus fetchgroup composite key
Is there a good step-by-step tutorial for using datanucleus and maven?

Categories

HOME
autohotkey
gulp
google-cloud-pubsub
virtual-machine
sip
locale
weblogic
intellisense
skypedeveloper
boxplot
django-middleware
watson-iot
cryengine
crm
okhttp3
squeak
xss
download
sugarcrm
foreach
liquidsoap
browserstack
clip-path
promotions
ejb-3.0
spring-data-solr
select2
drush
oxid
element
filehelpers
wallet
loader
url-parameters
descriptor
rndis
angular2-pipe
onclicklistener
android-xml
pixels
hierarchical-data
uibarbuttonitem
opencsv
webclient
odp.net
minitest
cache-control
ragel
maven-2
jibx
gem-fury
lfe
office-interop
android-graphview
php-mongodb
head
mef
spring-cloud-bus
openxava
monaca
wicketstuff
acceleo
ownership
cedar-bdd
indoor-positioning-system
hoare-logic
diameter-protocol
django-celery
laterjs
periodic-processing
videoview
dnvm
tooltwist
playn
teamwork
httpmodule
applinks
uiblureffect
novell
ios-enterprise
isl
cs193p
pidgin
adabas
ekevent
xrandr
wpd
leap-year
cocotron
architectural-patterns
biztalk-deployment
blotter
correctness
linear-interpolation
towerjs
parallel-python
jqtransform
designated-initializer
cpack
silverlight-2.0
file-storage
datadude
httpbrowsercapabilities
ironpython-studio

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App