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
model-view-controller
system-calls
jenkins-pipeline
formatting
abc
apache-storm
dynamic
livecharts
data-modeling
jshell
docker-compose
open-search-server
vsixmanifest
soap-client
activejdbc
desktop-application
resharper
oxid
element
logstash-configuration
openstack-horizon
dompdf
multibinding
brightway
amazon-data-pipeline
openam
alert
project-reactor
accordion
aws-devicefarm
single-page-application
keystone
git-branch
hololens
google-drive-android-api
connection-pooling
onclicklistener
prepros
ithit-webdav-server
sha
grunt-contrib-uglify
multiple-inheritance
hierarchical-data
hierarchy
mobile-development
andengine
wordpress-rest-api
wercker
machine-code
aweber
console.readline
dotnetnuke-module
form-fields
definition
gradlew
azure-data-catalog
confluent
emacs24
history
vertex
photoshop-script
dmalloc
bipartite
apache-commons-cli
addressbook
strtol
eclipse-mars
scriptengine
jigsaw
hfp
audiorecord
shtml
jmh
pebble-js
std
fadein
opendolphin
jcomponent
tooltwist
pagecontrol
screen-lock
asp.net-2.0
mri
launcher
jsonschema2pojo
unityvs
system.io.packaging
react-os
powershell-v1.0
time-frequency
switchpreference
winrun4j
farpoint-spread
slimscroll
cvi
html5-filesystem
nomachine
mdp
ekevent
xml-validation
ie-developer-tools
tlbimp
cab
infomaker
zend-db-table
maven-webstart-plugin
bho
gwt2
ntdll
rbm
dnsbl
databus
winrt-async
pdf-reader
optimistic-concurrency
eeprom
commonsware
jqzoom
mscorlib
llblgen
s60
conditional-operator
jquery-attributes
mysql-logic
code-golf
memory-consumption

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