Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

Embedding our jar file into OSGI bundle fails.

Avatar

Level 7

 

hi folks

I am trying to embed one of our java client libraries into AEM.

 

I followed:

https://www.linkedin.com/pulse/how-add-third-party-bundle-you-aem-package-veena-vikraman/

 

in ui.apps, I created an "install" directory with the client lib ( which was converted into a OSGi bundle)

In content-package-maven-plugin, I added "embeddeds" and "embedded" and added the  group, artifact id and the target directory.

 

in aem.core,for "maven-bundle-plugin" I added the artifact id to the Embed-Dependency list.

 

 I added Dependencys to aem.core and the parent pom.xmls... with scope of "provided".

 

However I got these errors. Am I missing some step?

 

thanks.

Fiona

 

[WARNING] The POM for com.xxx.xxx-api-client-jdk8:jar:1.20.0-SNAPSHOT is missing, no dependency information available

 

:[ERROR] Failed to execute goal on project aem.core: Could not resolve dependencies for project com.xxxx.aem.core:bundle:1.0.0-SNAPSHOT: Could not find artifact com.xx.xxxx-api-client-jdk8:jar:1.20.0-SNAPSHOT -> [Help 1]

 

 

1 Accepted Solution

Avatar

Correct answer by
Level 2

Hi fionas,

I have similar restriction in my project with a third-party jar which is not available to download via maven dependency.

Here is what I did and it's working perfectly with cloud manager deployments.

- Using maven local repository concept and create a local repo within the project structure and commit it as part of your codebase.

- Refer the local repo within the main pom.xml under the <repositories> section.

- Add the third party jar as any other maven dependency using the <dependency> tag.

- Export the classes of your jar file using <plugin> --> maven-bundle-plugin --> <_exportcontents> tag.

 

Checkout the screenshots to get a idea.

 

Thanks,

Sudheer.

View solution in original post

16 Replies

Avatar

Community Advisor

Hello @fionas76543059 

 

jar to bundle conversion:

- When we convert a jar to bundle, we need to make sure that the Manifest file has proper exports.

- The easiest way to convert a jar to bundle is to use bnd tool. It can be downloaded from http://www.java2s.com/Code/Jar/b/Downloadbndjar.htm

- Once downloaded, execute following command 

Command: 

java -jar bnd.jar wrap <your_jar>.jar

- A file will be generated, change its extension to .jar

 

Deploying bundle to AEM: Multiple approaches

  1. Using artifactory like Jfrog. You would need to add the bundle to artifactory and configure pom.xml of your project to download the dependency from artifactory .
  2. Using the install folder as suggested on How to add a third party bundle to your AEM package ? (linkedin.com)

Key is to get your jar->bundle right first

 


Aanchal Sikka

Avatar

Community Advisor

Hello @fionas76543059 ,

The process you followed should work for an OSGI-ready jar. But some jar files are not installed in OSGI by this process. You can follow this documentation to install your jar file into OSGI. https://myaemlearnings.blogspot.com/2021/08/embedding-third-party-dependencyosgi.html 

 

For this, you need to add an extra module, I Hope this will help you. 

 

 

Avatar

Level 7

Thanks for all the suggestions.

 

Our API code is proprietary, not in a public repo, and  our company repository is not contactable for the Adobe pipelines.

 

I am hoping that when I install the OSGi bundle that I have made from my code, that the Adobe pipeline will put the code into its /root/.m2/repository to be available as a dependency to compile the code in "core"

 

I wonder does the order of the modules matter?

 

 

Avatar

Community Advisor

I don't think so. I tried both ways to embed that additional module before and after the core module. Yes, both times it runs fine. 

Avatar

Level 7

oK, thanks,  Have you ever tried it with a bit of proprietary code that isn't available in a public maven repo ?

Avatar

Community Advisor

Yes, On that case you can put your project as private repository manage by s3.
Check this documentation: https://github.com/seahen/maven-s3-wagon 

Step 1: Need to deploy your private codebase to s3.

       <extensions>
            <extension>
                <groupId>com.github.seahen</groupId>
                <artifactId>maven-s3-wagon</artifactId>
                <version>1.3.3</version>
            </extension>
        </extensions>
    <distributionManagement>
        <repository>
            <id>s3-snapshots</id>
            <url>s3://your-private-repo/releases</url>
        </repository>
        <snapshotRepository>
            <id>s3-snapshots</id>
            <url>s3://your-private-repo/snapshots</url>
        </snapshotRepository>
    </distributionManagement>

Setup the S3 access key in .m2/settings.xml and put the credential in PC environment variable.

Step 2:: Deploy the project in s3 using mvn clean deploy

Step 3: Import your private project into your client project as a maven dependency.

 

Note: These all are the overall idea. But it's very popular for private repository management. You can do some research and POC to execute this.

 

Another way can be to use NEXUS Repository Management. But this will lead you to some additional server manage costs.

Avatar

Level 7

Thanks !

I can't have a public repo in S3 or nexus.

 

I was hoping your approach 2 in your link above meant I didn' t need a public repo.

2. As a separate module in AEM project code base. 
 
I have all the code in my proprietary jar file (that I can turn into a bundle)...
Can't the Cloud manager pipeline  put that in its local repo in .m2 ?
 
thanks
Fiona
 

 

Avatar

Community Advisor

Hello @fionas76543059 

 

If you can create the jar as a bundle in Project, CM/maven will be able to compile and put it in .m2 repository.

 

Yes, the order matters. Please assure that this converted bundle is added as a dependency in the other core bundle used in the project. That way, it will compile first, install in .m2 first and will be ready to be used by the other bundle.

 

For the other bundle to be able to use it, make sure that the Export-Packages etc of converted target are configured properly.

 

In case, you are doubtful about how to configure MANIFEST.MF, please take help of the bnd tool. You can create a bundle, extract the MANIFEST.MF and use in your converted module


Aanchal Sikka

Avatar

Community Advisor

No, maybe you didn't get my point. Using S3 wagon or Nexus you can create your own repository management tool. That will feel like Maven Public Repository. But without a proper credential, no one can access your repository.

These actually make your dependency as a private dependency.

In your last question, I don't think so, You won't have that access to put jar in cloud m2. Most importantly that's not recommended at all and its a very risky job.

Avatar

Level 6

@fionas76543059 

The method you are following should work. Did you add the dependency in apps pom.xml where you are actually trying to embed it?

 

Avatar

Correct answer by
Level 2

Hi fionas,

I have similar restriction in my project with a third-party jar which is not available to download via maven dependency.

Here is what I did and it's working perfectly with cloud manager deployments.

- Using maven local repository concept and create a local repo within the project structure and commit it as part of your codebase.

- Refer the local repo within the main pom.xml under the <repositories> section.

- Add the third party jar as any other maven dependency using the <dependency> tag.

- Export the classes of your jar file using <plugin> --> maven-bundle-plugin --> <_exportcontents> tag.

 

Checkout the screenshots to get a idea.

 

Thanks,

Sudheer.

Avatar

Level 7

hi, I tried your idea but it didn't work for me : -(

 

I created a repository directory at the top level and put the jar file in there.

 

I ran this command.

mvn org.apache.maven.plugins:maven-install-plugin:3.1.1:install-file -Dfile="./repository/./xx-api-client-jdk8-1.21.0-SNAPSHOT.jar" -DgroupId=com.xxxx -DartifactId=xxx-api-client-jdk8 -Dversion=1.21.0-SNAPSHOT -Dpackaging=jar -DlocalRepositoryPath=repository -DgeneratePom=true

 

I then removed the jar and pushed the results of the above command to cloudmanager. It had files called xxx-api-client-jdk8-1.21.0-SNAPSHOT.pom and xxx-api-client-jdk8-1.21.0-SNAPSHOT.jar at the bottom of the directory tree .... repository/com/xxxx/xxx-api-client-jdk8/1.21.0-SNAPSHOT.

There is also  _remote.repositories and maven-metadata-local.xml files, not sure what they are.

I also added the config for the local repository exactly the same as you stated.

 

Anyhow, I still didn't get any success.


09:51:10,656 [main] [INFO] Downloading from project.local: file:{project.basedir}/repository/com/xxx/xxxxl-api-client-jdk8/1.21.0-SNAPSHOT/maven-metadata.xml
09:51:10,678 [main] [INFO] Downloading from project.local: file:{project.basedir}/repository/com/xxx/xxxx-api-client-jdk8/1.21.0-SNAPSHOT/xxxx-api-client-jdk8-1.21.0-SNAPSHOT.pom
09:51:10,686 [main] [WARNING] The POM for com.xxxx:xxxx-api-client-jdk8:jar:1.21.0-SNAPSHOT is missing, no dependency information available
09:51:11,097 [main] [INFO] Downloading from central: https

 

?

 

Any ideas?

Thanks Fiona

 

Avatar

Community Advisor

Hi @fionas76543059 

 

You can embed the jar using the following way:

  • In AEMasCS project/ archetype project with version >= 24, OSGi bundle out of core module is embedded in all module as opposed to ui.apps module (Old project structure)
  •  Add dependency for third party jar in all pom.xml
  • Add <embedded> tag for dependency jar in <embeddeds> section of filevault-package-maven-plugin of all pom.xml like this
     
    <embedded>
        <groupId>GROUP_IDd>
        <artifactId>ARTIFACT_ID</artifactId>
        <target>/apps/myproject-packages/content/install</target>
    </embedded>

  • The build will add the jar file on the above mentioned path in repository and jar will be treated as an OSGI bundle

Thanks,

Nupur

Avatar

Level 7

Thanks everyone for your great feedback.

Actually I gave up in the end  and manually copied over the files from the API into my project.

But I learned a lot about OSGi and will make another attempt some other time!