Reputation: 812
I need to pack a jar
(or a war
, format is irrelevant, please read further) with the structure of common war
(wab
) archive. Meaning that I need WEB-INF/classes/lib
folder filled with dep-cy jar
s (not flattened/shaded) and all common stuff like resources, etc.
So, the main difference with the very common NON-osgi war
would be a properly written manifest. The problem is that BND
processes on the Jar
task of Gradle
, and then war plugin messes everything.
Right now I have reached the solution but I am not satisfied with it. And overall I feel there should be a better way. There are mostly two strategies:
war
plugin and rely on BND
rich capabilites.war
pluging but rearrange somehow the build, so it does it's thing but lets the BND
do its thing as well supposedly AFTER the war
. (So, FIRST the WAR
the BND
is AFTER.)A little input data. I believe the is a major SUPER_BUG in bnd since everything I said is supposed to work with just one directive -wablib
, however, the major issue with it is that it works somehow in a diffwrent way rather than -includeresource
for exemple. -wablib
gets the input some sort of full_path_to_resource, which is not available while project evaluation and resolution by gradle and overall, it COULD be just brilliant IF it could take just a jar_name.jar
as includeresource
does. But it's not! So, even after trying to pull a string with full paths to all dependencies it is never done as gradle's configuration is not allowed to be manually resolved
to get those paths.
On the other hand the second listed way works but it looks and feels like a crutch. Like it should not be that way. I mean manually constructing the Bundle-ClassPath
and Include-Resources
How to painlessly create WAR
s WAB
s with war
gradle
plugin preferrably and not flattened/shaded?
Snippet (UPDATED)
I managed to avoid explicitly constructing manifestClasspath by just adding ;lib:=true
so bnd does it's thing.
tasks.withType<Jar> {
manifest {
val manifestIncludeJars = configurations.
implementation.
incoming.
dependencies.
joinToString(",") {
"lib/${it.name}.jar=${it.name}-[0-9]*.jar;lib:=true"
}
attributes(mapOf(
SNAPSHOT to "\${tstamp}-SNAPSHOT",
"Automatic-Module-Name" to "${project.group}.\${replace;\${bsn};[-_];.}",
BUNDLE_VERSION to project.version,
INCLUDERESOURCE to manifestIncludeJars
))
}
}
UPDATE
Also I managed to get what I want by just using bnd without gradle 'war' plugin. But that's not what I want. This constructs the whole jar
/war
/wab
whatever you call it with exactely the same structure as gradle 'war' plugin plus the proper manifest, but I want to separate the the proper manifest creation from assembling the archive so no delegation from gradle to bnd of the build tool functions
# [ WEB(APP) / WAB / WAR ]
-wab: src/main/webapp
-includeresource: WEB-INF/classes=src/main/resources
# This does the magic since gradle and bnd share properties during build
deps: ${project.sourceSets.main.runtimeClasspath.files}
# remove the square bracket form the last dependency so it to be incuded in archive
lastDep: {substring;${last;${deps}};0;-1}
-wablib: ${format;%s,;${filter;${deps},${lastDep};.*\.jar$}}
Upvotes: 1
Views: 601
Reputation: 812
Eventually, BJ Hargrave said that there are no direct way to use WAR Gradle plugin and bnd Gradle plugin simultaneously, so the way to go is just one or another.
Bnd Gradle plugin does not support same directory structure as canonical war project with Gradle WAR plugin, so there could be difficulties. Also, generated artifact despite has WAR-like structure, it is still a .jar
. But generally, I could achieve the desired structure with just bnd-tools Gradle plugin.
P.S. The question and answer is only for non-workspace setup and for bnd-gradle-builder plugin
here is my war (e.g web) project's bnd.bnd
(NON-workspace)
# ___ ___ ____ ____________ ________ __________
# / _ | / _ \__ / / / / / __/_ __/ /_ __/ // / _/ __/
# / __ |/ // / // / /_/ /\ \ / / / / / _ // /_\ \
# /_/ |_/____/\___/\____/___/ /_/ /_/ /_//_/___/___/
#
# ADJUST THIS
# [ BLUEPRINT ] //overrides Blueprint header if exists
Bundle-Blueprint:
# [ IMPEXP ]
-exportcontents: ${packages;ANNOTATED;org.osgi.annotation.versioning.Version}
Import-Package: *
# [ WEB(APP) / WAB / WAR ]
Web-ContextPath: /myapp
# //Pax Web support not 100% OSGi 4.2 compliant https://ops4j1.jira.com/browse/PAXWEB-206
Webapp-Context: /myapp
-wab: src/main/webapp
# // for instance regex for end and start (^\[)|(\]$)
-wablib: ${format;%s,;${filter;${substring;${project.sourceSets.main.runtimeClasspath.files};1;-1};.*\.jar$}}
# __ ______ __________ __ _ ______ _______ _____ _ _______________
# / / / _/ //_/ __/ /\ \/ / / |/ / __ \ / ___/ // / _ | / |/ / ___/ __/ __/
# / /___/ // ,< / _// /__\ / / / /_/ / / /__/ _ / __ |/ / (_ / _/_\ \
# /____/___/_/|_/___/____//_/ /_/|_/\____/ \___/_//_/_/ |_/_/|_/\___/___/___/
#
# // probably no changes needed
Bundle-Description: ${project.description}
Bundle-DocURL: ${project.bundleDocURL}
Bundle-Version: ${project.version}
Automatic-Module-Name: ${project.group}.${replace;${bsn};[-_];.}
-snapshot: ${tstamp}-SNAPSHOT
-pedantic: true
-sources: false
-runee: JavaSE-${project.javaManifestVersion}
-pom: true
-fixupmessages: "Classes found in the wrong directory";is:=warning
non-war (non-web) project
# ___ ___ ____ ____________ ________ __________
# / _ | / _ \__ / / / / / __/_ __/ /_ __/ // / _/ __/
# / __ |/ // / // / /_/ /\ \ / / / / / _ // /_\ \
# /_/ |_/____/\___/\____/___/ /_/ /_/ /_//_/___/___/
#
# [ BLUEPRINT ] //overrides Blueprint header if exists
Bundle-Blueprint:
# [ IMPEXP ]
-exportcontents: ${packages;ANNOTATED;org.osgi.annotation.versioning.Version}
Import-Package: *
# __ ______ __________ __ _ ______ _______ _____ _ _______________
# / / / _/ //_/ __/ /\ \/ / / |/ / __ \ / ___/ // / _ | / |/ / ___/ __/ __/
# / /___/ // ,< / _// /__\ / / / /_/ / / /__/ _ / __ |/ / (_ / _/_\ \
# /____/___/_/|_/___/____//_/ /_/|_/\____/ \___/_//_/_/ |_/_/|_/\___/___/___/
#
# // probably no changes needed
Bundle-Description: ${project.description}
Bundle-DocURL: ${project.bundleDocURL}
Bundle-Version: ${project.version}
Automatic-Module-Name: ${project.group}.${replace;${bsn};[-_];.}
-snapshot: ${tstamp}-SNAPSHOT
-pedantic: true
-sources: false
-runee: JavaSE-${project.javaManifestVersion}
-pom: true
-fixupmessages: "Classes found in the wrong directory";is:=warning
Also, since then bnd-tools started to support multi-jar projects, so fixupmessages
could be avoided and maybe some other stuff should be adjusted accordingly.
Upvotes: 0