Bundling extra dependencies in an OBR in correct way

e.g follow the instructions from the Confluence ‘Hello World’ Macro or Jira ‘Hello World’ Macro

open pom.xml file and change/add on the configuration of the maven plugin:

add your dependencies as normal - like:

		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-collections4</artifactId>
			<version>4.4</version>
		</dependency>

on this section:

		<plugins>
			<plugin>
				<groupId>com.atlassian.maven.plugins</groupId>
				<artifactId>confluence-maven-plugin</artifactId>
				<version>${amps.version}</version>
				<extensions>true</extensions>
				
				<configuration>
  1. add <extractDependencies>false</extractDependencies>
  2. remove the <Import-Package>...</Import-Package> (will be created automatically - that’s what maven is for…)
  3. add
    <Bundle-ClassPath>.,{maven-dependencies}</Bundle-ClassPath>
    <Embed-Dependency>*;scope=runtime</Embed-Dependency>
    <Embed-Directory>META-INF/lib</Embed-Directory>

result should look like this for conflunence:

<plugin>
				<groupId>com.atlassian.maven.plugins</groupId>
				<artifactId>confluence-maven-plugin</artifactId>
				<version>${amps.version}</version>
				<extensions>true</extensions>
				
				<configuration>
					<productVersion>${confluence.version}</productVersion>
					<productDataVersion>${confluence.data.version}</productDataVersion>
					<enableQuickReload>true</enableQuickReload>
					
					<extractDependencies>false</extractDependencies>

					<!-- See here for an explanation of default instructions: -->
					<!--
					https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
					<instructions>
						<Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>

						<!-- Add package to export here 
						<Export-Package>
							com.myown.api
						</Export-Package>
						-->
						
						<!-- Add package import here -->
						
						<Bundle-ClassPath>.,{maven-dependencies}</Bundle-ClassPath>
						<Embed-Dependency>*;scope=runtime</Embed-Dependency>
						<Embed-Directory>META-INF/lib</Embed-Directory>
						
						<!-- Ensure plugin is spring powered -->
						<Spring-Context>*</Spring-Context>
					</instructions>
				</configuration>
			</plugin>

do the
atlas-clean
atlas-package

In the resulting jar / obr you will find all your dependencies inside jira-helloworld-1.0.0-SNAPSHOT.jar\META-INF\lib\ instead of unpacking and repackage in one new jar (NO GO!)

build

PS: This Managing dependencies (atlassian.com) results in a big mess of everything in one jar file

@MarcoPaleani can you elaborate why the extracting of dependencies is a NO-GO?

And perhaps @mpaisley can tell us why Atlassian opted for extraction in the first place?

There are multiple arguments to don’t extract libs and repackage it. Also there are some existing, where it is not working - e.g. try to create a single jar with an jdbc access to oracle.

Yes, in such cases you can work with workarounds and make such libs in an OSGI context available. Instead of doing it right in the beginning in the correct way :wink:

The reason I’m asking is because I’ve been shipping Atlassian P2 apps since 2012 and I’ve never had any issue with the extraction / repackaging strategy by Atlassian. I also reckon that this is a fairly common practice with a lot of other apps as well.

You are stating this as a “NO GO”, which is a strong sentiment, so I would love to hear your argument as to why a practice that has been done for over a decade is something that should be reconsidered.

how you deal with signed jars like oracle.jdbc, bouncy castle …
how you deal with complex dependencies? How you control, what class / file is taken in your resulting jar?
there is something inside your jar, that not belongs to you
what about licensing? are you allowed to “modify” that jars?

→ all of these is solved by doing it right with minimal effort