I am upgrading a springboot app from 1.X to 2.1.3.RELEASE. My Springboot is a multi module project setup which is triggered using a java command something similar to this.
java -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5088 -Drun.jvmArguments="-Xdebug" -Dloader.path=C:\code\build\libs\dir\ -jar C:\code\build/libs/core.jar --spring.config.location=C:\config\application.properties
This is how the project structure looks like
App
Common
Core (has the main class)
Sub
Before the upgrade : Manifest.mf file of core.jar looks like this
Manifest-Version: 3.2.15.signature.LOCALDEV
Project-Name: core
Built-By: dkumar
Built-Date: 2020-11-10 16:09
Project-Version: 3.2.15.signature.LOCALDEV
Spring-Boot-Version: 1.5.1.RELEASE
Main-Class: org.springframework.boot.loader.PropertiesLauncher
Git-Branch: signature
Start-Class: com.demo.Main
Spring-Boot-Classes: BOOT-INF/classes/
Git-Commit-Hash: signature
Project-Group: com.demo.print
Spring-Boot-Lib: BOOT-INF/lib/
After the upgrade. This what the manifest.mf file looks like
Manifest-Version: 3.1.87.upgradespring.LOCALDEV
Git-Branch: upgradespring
Project-Name: core
Built-By: dkumar
Built-Date: 2020-11-18 18:15
Start-Class: com.demo.Main
Git-Commit-Hash: upgradespring
Project-Group: com.demo.print
Project-Version: 3.1.87.upgradespring.LOCALDEV
Main-Class: org.springframework.boot.loader.JarLauncher
Before the upgrade the following property in my Core build.gradle took care of using org.springframework.boot.loader.PropertiesLauncher which inturn used -Dloader.path to load all the Sub (subprojects) jars on to the classpath
springBoot{
mainClass = "com.demo.Main"
layout = "ZIP"
}
After the upgrade, the layout property is now deprecated in 2.1.3.RELEASE and the Main-Class is now changed to Main-Class: org.springframework.boot.loader.JarLauncherand this doesn't support the usage of -Dloader.path (I think). Because of this I always get No bean found error when i try to invoke a class of Sub (subproject). This happens because -Dloader.path fails to include the JARS from subproject onto the classpath. Before the upgrade I could see the relevant jars on the class path.
I tried several ways to change the Main-Class attribute within the manifest to use PropertiesLaucher but none seem to have worked. I have also looked at the plugin documentation and tried something similar but that to didn't work
https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/gradle-plugin/reference/html/#packaging-executable-configuring-properties-launcher
I think by changing the Main-class I can solve this problem but I am not sure how to do that.
Any suggestions or idea would be helpful. All comments are welcome. I will update the question if the need arises.
I apologize in advance as i am unable to place a larger code snippet due corporate policies.
I was able to resolve this by adding the following properties
bootJar {
manifest {
attributes(
'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher',
'Spring-Boot-Classes': 'BOOT-INF/classes/',
'Spring-Boot-Lib': 'BOOT-INF/lib/'
)
}
}
Only this should work as well within the manifest:
'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher'
I've done a successfull mvn clean install on the project I built and the structure appears correct, all classes included and manifest is under META-INF including class-paths and main-class. Not sure what's not matching up here, but the class contents are valid when I checked contents using javap. Main method is present in the redacted_automatedSupport class and is also public.
Error:
host MINGW64 ~/Desktop/Projects/redacted_Automated_Support/target (master)
$ java -jar redacted_automatedSupport-1.0.jar
Error: Could not find or load main class support.redacted_automatedSupport
host MINGW64 ~/Desktop/Projects/redacted_Automated_Support/target (master)
$ java -cp redacted_automatedSupport-1.0.jar support.redacted_automatedSupport
Error: Could not find or load main class support.redacted_automatedSupport
host MINGW64 ~/Desktop/Projects/redacted_Automated_Support/target (master)
$
Manifest contents:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: bennet.vella
Class-Path: aws-java-sdk-s3-1.11.696.jar aws-java-sdk-kms-1.11.696.jar
aws-java-sdk-core-1.11.696.jar commons-logging-1.1.3.jar httpclient-
4.5.9.jar httpcore-4.4.11.jar commons-codec-1.11.jar ion-java-1.0.2.j
ar jackson-databind-2.6.7.3.jar jackson-annotations-2.6.0.jar jackson
-core-2.6.7.jar jackson-dataformat-cbor-2.6.7.jar joda-time-2.8.1.jar
jmespath-java-1.11.696.jar groovy-3.0.1.jar groovy-json-3.0.1.jar gr
oovy-dateutil-3.0.1.jar
Created-By: Apache Maven 3.6.3
Build-Jdk: 1.8.0_231
Main-Class: support.redacted_automatedSupport
Jar Archive Contents (renamed to zip to browse):
Support Jar Contents (removed some unecessary data, all names match):
It is not a complete answer, since it doesn't target the Maven issue I was having, but I did solve the IntelliJ problem I had with the wrong manifest file - and that's because I was creating the manifest in src/main/java when it should have been src/main/resources. This should hopefully alleviate some users' problems.
I have not however resolved how to properly build and include all relevant dependent jars using Maven - intelliJ does this successfully.
I have two bundles, A export two packages, and then B use these two packages(org.dom4j , org.dom4j.io) , and B still uses spring packages exported by other bundles. If I load bundle A then load bundle B in the osgi console, there is no resolver issue.
But, if I put these two packages into a par, if would fail in the synthetic.context bundle, saying "Uses violation:
A's manifest:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: device-openapi
Bundle-SymbolicName: device-openapi
Bundle-Version: 1.0.0
Export-Package: com.google.gson,
com.google.gson.annotations,
com.google.gson.internal,
com.google.gson.internal.bind,
com.google.gson.reflect,
com.google.gson.stream,
org.apache.commons.codec,
org.apache.commons.codec.binary,
org.apache.commons.codec.digest,
org.apache.commons.codec.language,
org.apache.commons.codec.language.bm,
org.apache.commons.codec.net,
org.apache.commons.io,
org.apache.commons.io.comparator,
org.apache.commons.io.filefilter,
org.apache.commons.io.input,
org.apache.commons.io.monitor,
org.apache.commons.io.output,
org.apache.commons.lang3,
org.apache.commons.lang3.builder,
org.apache.commons.lang3.concurrent,
org.apache.commons.lang3.event,
org.apache.commons.lang3.exception,
org.apache.commons.lang3.math,
org.apache.commons.lang3.mutable,
org.apache.commons.lang3.reflect,
org.apache.commons.lang3.text,
org.apache.commons.lang3.text.translate,
org.apache.commons.lang3.time,
org.apache.commons.lang3.tuple,
org.apache.commons.logging,
org.apache.commons.logging.impl,
org.apache.http,
org.apache.http.annotation,
org.apache.http.auth,
org.apache.http.auth.params,
org.apache.http.client,
org.apache.http.client.config,
org.apache.http.client.entity,
org.apache.http.client.methods,
org.apache.http.client.params,
org.apache.http.client.protocol,
org.apache.http.client.utils,
org.apache.http.concurrent,
org.apache.http.config,
org.apache.http.conn,
org.apache.http.conn.params,
org.apache.http.conn.routing,
org.apache.http.conn.scheme,
org.apache.http.conn.socket,
org.apache.http.conn.ssl,
org.apache.http.conn.util,
org.apache.http.cookie,
org.apache.http.cookie.params,
org.apache.http.entity,
org.apache.http.entity.mime,
org.apache.http.entity.mime.content,
org.apache.http.impl,
org.apache.http.impl.auth,
org.apache.http.impl.client,
org.apache.http.impl.conn,
org.apache.http.impl.conn.tsccm,
org.apache.http.impl.cookie,
org.apache.http.impl.entity,
org.apache.http.impl.execchain,
org.apache.http.impl.io,
org.apache.http.impl.pool,
org.apache.http.io,
org.apache.http.message,
org.apache.http.params,
org.apache.http.pool,
org.apache.http.protocol,
org.apache.http.util,
org.apache.log4j,
org.apache.log4j.chainsaw,
org.apache.log4j.config,
org.apache.log4j.helpers,
org.apache.log4j.jdbc,
org.apache.log4j.jmx,
org.apache.log4j.lf5,
org.apache.log4j.lf5.util,
org.apache.log4j.lf5.viewer,
org.apache.log4j.lf5.viewer.categoryexplorer,
org.apache.log4j.lf5.viewer.configure,
org.apache.log4j.net,
org.apache.log4j.nt,
org.apache.log4j.or,
org.apache.log4j.or.jms,
org.apache.log4j.or.sax,
org.apache.log4j.pattern,
org.apache.log4j.rewrite,
org.apache.log4j.spi,
org.apache.log4j.varia,
org.apache.log4j.xml,
org.dom4j,
org.dom4j.bean,
org.dom4j.datatype,
org.dom4j.dom,
org.dom4j.dtd,
org.dom4j.io,
org.dom4j.jaxb,
org.dom4j.rule,
org.dom4j.rule.pattern,
org.dom4j.swing,
org.dom4j.tree,
org.dom4j.util,
org.dom4j.xpath,
org.dom4j.xpp,
org.json,
org.wcc.crypt,
org.wcc.framework
Import-Package: javax.crypto,javax.crypto.spec,javax.naming,javax.nami
ng.directory,javax.naming.event,javax.naming.ldap,javax.naming.spi,ja
vax.net,javax.net.ssl,javax.security.auth.x500
B's manifest:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: NGCPlugin-service
Bundle-SymbolicName: com.myplugin.esdk.storage.service
Bundle-Version: 1.5.50
Bundle-Vendor: myplugin
Bundle-ClassPath: .
Tool: Bundlor 1.1.0.RELEASE
Export-Package: com.myplugin.esdk.storage.mvc,
com.myplugin.esdk.storage.service.datastore,
com.myplugin.esdk.storage.service.device,
com.myplugin.esdk.storage.service.host,
com.myplugin.esdk.storage.service.mount,
com.myplugin.esdk.storage.service.resource,
com.myplugin.esdk.storage.service.snapshot,
com.myplugin.esdk.storage.service.vm
Import-Package: org.apache.commons.logging,
org.dom4j,
org.dom4j.io,
org.json,org.w3c.dom,
org.xml.sax,
org.apache.commons.codec,
org.apache.commons.codec.binary,
org.apache.commons.codec.digest,
org.apache.commons.codec.language,
org.apache.commons.codec.language.bm,
org.apache.commons.codec.net,
org.apache.commons.io,
org.slf4j,
org.springframework.beans.factory.annotation
Error log:
Resolver report:
Uses violation: <Import-Package: org.springframework.beans.factory.annotation; version="0.0.0"> in bundle <com.myplugin.esdk.storage.ngc-2.1.7-com.myplugin.esdk.storage.service_1.5.50[1520387337960]>
Resolver reported uses conflict for import
An Import-Package could not be resolved. Resolver error data <Import-Package: com.myplugin.esdk.storage.service.snapshot; version="0.0.0">. Caused by missing constraint in bundle <com.myplugin.esdk.storage.ngc-2.1.7-synthetic.context_2.1.7>
constraint: <Import-Package: com.myplugin.esdk.storage.service.snapshot; version="0.0.0"> constrained to bundle <com.myplugin.esdk.storage.ngc-2.1.7-com.myplugin.esdk.storage.service> constrained bundle version range "[1.5.50,1.5.50]"
with attributes {module_scope=com.myplugin.esdk.storage.ngc-2.1.7}
Anyone knows how to fix this? I tried to make a dummy bundle which uses Import-Bundle to import the two bundle's all exported packages, after I manually loaed the A and B bundle, these is no resolver error......
I am not familiar with deployment of PAR files, when using Virgo I normally deploy PLAN files. This said, I suspect that the problem may be due to the fact that A exports a number of packages org.apache* which are probably already exported by other bundles included in Virgo and which are dependencies of Spring. So when your PAR is resolved, plan B finds itself in the situation in which the same package is being inherited from A and also from Spring via transitive dependencies.
I would try to remove from A manifest the export of all the packages that are already provided by Virgo.
As we know that by defaul osgi export-package only export the package from src/main/java folder,
but i need the other file form src/main/resource also to be exported to use by other projects.
Below is the example of my
ProjectA (packaging type is jar)
src/main/java
x.y.z.SomeClass.java
src/main/resource
x.y.z.config.SomeConfigFile.xml
pom.xml contains
<Export-Package>
x.y.z.*,
x.y.z.config.*,
*
</Export-Package>
ProjectB (packaging type is bundle)
src/main/java
a.b.c.AnotherClass.java
src/main/resource
a.b.c.config.AnotherConfigFile.xml
pom.xml contains
<Import-Package>
x.y.z.*,
x.y.z.config.*,
*
</Import-Package>
Here my requirement is to use SomeConfigFile.xml of ProjectA into AnotherConfigFile.xml of
projectB but i always get FileNotFoundException for the above scenario.
Please help me use the src/main/resource classpath files into another osgi project.
How i can achieve the above defined scenario.
You should probably use Include-Resource instead of Import-Package. More info on the header here (in the 'headers' section): http://www.aqute.biz/Bnd/Format.
There can be several issues (I guess it is option one but the others might be useful as well)
If there is no java class usage, you must specify the required package exactly at the Import-Package section. You cannot use asterisk.
If you want to export a package that is under META-INF, in the Export-Package section you must define it with a quote and an equality character. E.g: '=META-INF.subdir'
If you want to access a resource that is in an imported package, you cannot use the bundle.getResource() function as it searches only in the current bundle. You must use the classLoader of the bundle or the or listResources function of BundleWiring.
I am using wso2 Application Server 5.1.0.
I have deployed my own bundle having name demo-service which contains import-package definition in its manifest as below:
>Bundle-SymbolicName = demo-service
Import-Package = javax.sql,org.apache.commons.dbcp;version="[1.4,2)"
I tried to diagnose the most popular "uses conflict" in OSGi world for my case and I found that commons-dbcp_1.4.0.wso2v1.jar and commons-dbcp-1.4.jar both were converted to OSGi bundle by container and exported their packages with version "0.0.0" which can be observed from the output below:
>osgi> packages org.apache.commons.dbcp
org.apache.commons.dbcp; version="0.0.0"<commons-dbcp_1.4.0.wso2v1 [49]>
compass_2.0.1.wso2v2 [60] imports
org.wso2.carbon.core_4.1.0 [256] imports
org.wso2.carbon.registry.core_4.1.0 [377] imports
org.wso2.carbon.tenant.mgt_2.1.0 [434] imports
synapse-commons_2.1.1.wso2v3 [528] imports
synapse-core_2.1.1.wso2v3 [529] imports
org.apache.commons.dbcp; version="0.0.0"<commons_dbcp_1.4_1.0.0 [57]>
According to the requirement of my demo-service bundle it's not able to find
org.apache.commons.dbcp;version="[1.4,2)"
Is there any way to export the packages of commons-dbcp-1.4.jar after it gets converted from non-osgi bundle to osgi bundle because I need to make sure that my demo-service bundle should wire with commons-dbcp-1.4.jar..
In brief, any version of thirdparty jar I put in WSO2_HOME\repository\components\lib folder container exports it with version="0.0.0" .. which discourages the main concept for classloading of OSGi
please suggest if any workaround is possible in this case .. :)
Thanks ..
When a version is not specified while exporting packages OSGi defaults to version 0.0.0. In this case as it's automatically converting to osgi bundle it might not be having version explicitly specified. Sometimes this also helps to ensure that multiple versions of packages are not present.
In your case as you need to use the packages in the bundle put in repository\components\lib folder you could manually specify the version. The OSGi-fied bundles of the jars you put in repository\components\lib can be found in repository\components\dropins folder. Inside that bundle you will find the OSGi manifest file. In the manifest file manually specify the versions for the required packages under Export-Package category as follows.
org.apache.commons.dbcp;version=1.4.1
Then on startup, it would use these bundles and you should be able to export packages with specified version.