Hi.
Summary
WrenIDM currently bundles OrientDB 1.7.0 as a storage backend for development and evaluation purposes.
Due to incompatibility of OrientDB's dependencies and musl libc used on Alpine Linux (see details below), the WrenIDM cannot be used on Alpine (and Alpine based Docker images) without further changes to the build and OrientDB storage is unusable.
In this issue, I'd like to discuss possibilities of either OrientDB upgrade or replacement by different storage backend as a solution to this problem.
Problem
While trying to deploy and run current WrenIDM master branch (6d06406 as of now) on Alpine Linux v3.7, I get following error on OpenIDM startup:
Jun 25, 2018 3:33:18 PM org.forgerock.openidm.repo.orientdb.impl.OrientDBRepoService init
WARNING: Initializing database pool failed
com.orientechnologies.orient.core.exception.ODatabaseException: Cannot create database
at com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract.create(ODatabaseRecordAbstract.java:384)
at com.orientechnologies.orient.core.db.ODatabaseWrapperAbstract.create(ODatabaseWrapperAbstract.java:55)
at com.orientechnologies.orient.core.db.ODatabaseRecordWrapperAbstract.create(ODatabaseRecordWrapperAbstract.java:64)
at org.forgerock.openidm.repo.orientdb.impl.DBHelper.checkDB(DBHelper.java:316)
at org.forgerock.openidm.repo.orientdb.impl.DBHelper.getPool(DBHelper.java:100)
at org.forgerock.openidm.repo.orientdb.impl.OrientDBRepoService.init(OrientDBRepoService.java:866)
at org.forgerock.openidm.repo.orientdb.impl.OrientDBRepoService.getRepoBootService(OrientDBRepoService.java:810)
at org.forgerock.openidm.repo.orientdb.impl.Activator.start(Activator.java:64)
at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:697)
at org.apache.felix.framework.Felix.activateBundle(Felix.java:2226)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2144)
at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1371)
at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:308)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.orientechnologies.orient.core.exception.ODatabaseException: Cannot create database
at com.orientechnologies.orient.core.db.raw.ODatabaseRaw.create(ODatabaseRaw.java:139)
at com.orientechnologies.orient.core.db.ODatabaseWrapperAbstract.create(ODatabaseWrapperAbstract.java:55)
at com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract.create(ODatabaseRecordAbstract.java:338)
... 13 more
Caused by: com.orientechnologies.orient.core.exception.OStorageException: Error on creating record in cluster: com.orientechnologies.orient.core.storage.impl.local.paginated.OPaginatedCluster@1d1ef5c0
at com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage.createRecord(OLocalPaginatedStorage.java:691)
at com.orientechnologies.orient.core.config.OStorageConfiguration.create(OStorageConfiguration.java:394)
at com.orientechnologies.orient.core.storage.impl.local.OStorageConfigurationSegment.create(OStorageConfigurationSegment.java:49)
at com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage.create(OLocalPaginatedStorage.java:303)
at com.orientechnologies.orient.core.db.raw.ODatabaseRaw.create(ODatabaseRaw.java:135)
... 15 more
Caused by: java.lang.UnsatisfiedLinkError: /tmp/snappy-unknown-f952ea44-7c77-42b0-b2fd-4a3c1540afd8-libsnappyjava.so: Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /tmp/snappy-unknown-f952
ea44-7c77-42b0-b2fd-4a3c1540afd8-libsnappyjava.so)
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at org.xerial.snappy.SnappyLoader.loadNativeLibrary(SnappyLoader.java:166)
at org.xerial.snappy.SnappyLoader.load(SnappyLoader.java:145)
at org.xerial.snappy.Snappy.<clinit>(Snappy.java:47)
at com.orientechnologies.orient.core.compression.impl.OSnappyCompression.compress(OSnappyCompression.java:36)
at com.orientechnologies.orient.core.compression.impl.OAbstractCompression.compress(OAbstractCompression.java:30)
at com.orientechnologies.orient.core.storage.impl.local.paginated.OPaginatedCluster.createRecord(OPaginatedCluster.java:400)
at com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage.createRecord(OLocalPaginatedStorage.java:674)
... 19 more
-> -> Jun 25, 2018 4:08:33 PM org.forgerock.openidm.info.impl.HealthService$4 run
SEVERE: OpenIDM failure during startup, ACTIVE_NOT_READY: Not all modules started [] [org.forgerock.openidm.repo-orientdb] []
After printing OSGi SCR services in felix console shows that openidm-orientdb
service did not load:
-> scr list
BundleId Component Name Default State
Component Id State PIDs (Factory PID)
[ 7] org.forgerock.openidm.config.enhanced.starter enabled
[ 1] [unsatisfied reference] org.forgerock.openidm.config.enhanced.starter
[ 7] org.forgerock.openidm.config.manage enabled
[ 0] [unsatisfied reference] org.forgerock.openidm.config.manage
[ 12] org.forgerock.openidm.datasource.jdbc enabled
[ 12] org.forgerock.openidm.repo.jdbc enabled
[ 15] org.forgerock.openidm.cluster enabled
[ 17] org.forgerock.openidm.http.context enabled
[ 2] [active ] org.forgerock.openidm.http.context
[ 20] org.forgerock.openidm.selfservice enabled
[ 20] org.forgerock.openidm.selfservice.kba enabled
[ 20] org.forgerock.openidm.selfservice.kbaservice enabled
[ 4] [unsatisfied reference] org.forgerock.openidm.selfservice.kbaservice
[ 20] org.forgerock.openidm.selfservice.propertymap enabled
[ 20] org.forgerock.openidm.selfservice.userupdate enabled
[ 3] [unsatisfied reference] org.forgerock.openidm.selfservice.userupdate
[ 33] org.forgerock.openidm.endpoint enabled
[ 35] org.forgerock.openidm.managed enabled
[ 35] org.forgerock.openidm.recon enabled
[ 5] [active ] org.forgerock.openidm.recon
[ 35] org.forgerock.openidm.sync enabled
[ 7] [unsatisfied reference] org.forgerock.openidm.sync
[ 35] org.forgerock.openidm.synchronization enabled
[ 6] [unsatisfied reference] org.forgerock.openidm.synchronization
[ 48] org.forgerock.openidm.script enabled
[ 48] org.forgerock.openidm.script.ScriptedPatchValueTransformerFactory enabled
[ 8] [unsatisfied reference] org.forgerock.openidm.script.ScriptedPatchValueTransformerFactory
[ 50] org.forgerock.openidm.security enabled
[ 9] [unsatisfied reference] org.forgerock.openidm.security
[ 58] org.forgerock.openidm.maintenance enabled
[ 11] [active ] org.forgerock.openidm.maintenance
[ 58] org.forgerock.openidm.maintenance.filter enabled
[ 15] [active ] org.forgerock.openidm.maintenance.filter
[ 58] org.forgerock.openidm.maintenance.update enabled
[ 16] [active ] org.forgerock.openidm.maintenance.update
[ 58] org.forgerock.openidm.maintenance.update.archives enabled
[ 13] [active ] org.forgerock.openidm.maintenance.update.archives
[ 58] org.forgerock.openidm.maintenance.update.config enabled
[ 10] [active ] org.forgerock.openidm.maintenance.update.config
[ 58] org.forgerock.openidm.maintenance.update.log enabled
[ 12] [active ] org.forgerock.openidm.maintenance.update.log
[ 58] org.forgerock.openidm.maintenance.updatemanager enabled
[ 14] [active ] org.forgerock.openidm.maintenance.updatemanager
[ 62] org.forgerock.openidm.audit enabled
[ 62] org.forgerock.openidm.audit.filter enabled
[ 17] [active ] org.forgerock.openidm.audit.filter
[ 72] org.forgerock.openidm.auth.config enabled
[ 18] [active ] org.forgerock.openidm.auth.config
[ 72] org.forgerock.openidm.authentication enabled
[ 75] org.forgerock.openidm.config.enhanced enabled
[ 19] [active ] org.forgerock.openidm.config.enhanced
[ 79] org.forgerock.openidm.health enabled
[ 20] [active ] org.forgerock.openidm.health
[ 79] org.forgerock.openidm.info enabled
[ 87] org.forgerock.openidm.identityProvider enabled
[ 87] org.forgerock.openidm.identityProviders enabled
[ 90] org.forgerock.openidm.openicf.syncfailure enabled
[ 21] [unsatisfied reference] org.forgerock.openidm.openicf.syncfailure
[ 90] org.forgerock.openidm.provisioner.openicf enabled
[ 90] org.forgerock.openidm.provisioner.openicf.connectorinfoprovider enabled
[ 22] [active ] org.forgerock.openidm.provisioner.openicf.connectorinfoprovider
[ 99] org.forgerock.openidm.external.rest enabled
[ 23] [active ] org.forgerock.openidm.external.rest
[ 102] org.forgerock.openidm.router enabled
[ 102] org.forgerock.openidm.router.internal enabled
[ 24] [active ] org.forgerock.openidm.router.internal
[ 104] org.forgerock.openidm.policy enabled
[ 112] org.forgerock.openidm.keystore enabled
[ 25] [active ] org.forgerock.openidm.keystore
[ 112] org.forgerock.openidm.keystore.impl.manager enabled
[ 27] [active ] org.forgerock.openidm.keystore.impl.manager
[ 112] org.forgerock.openidm.keystore.sharedkey enabled
[ 28] [active ] org.forgerock.openidm.keystore.sharedkey
[ 112] org.forgerock.openidm.truststore enabled
[ 26] [active ] org.forgerock.openidm.truststore
[ 115] org.forgerock.openidm.messaging enabled
[ 118] org.forgerock.openidm.crypto enabled
[ 29] [active ] org.forgerock.openidm.crypto
[ 121] org.forgerock.openidm.workflow enabled
[ 136] org.forgerock.openidm.provisioner enabled
[ 30] [active ] org.forgerock.openidm.provisioner
[ 158] org.forgerock.openidm.ui.context enabled
[ 163] org.forgerock.openidm.api-servlet enabled
[ 33] [unsatisfied reference] org.forgerock.openidm.api-servlet
[ 163] org.forgerock.openidm.error-servlet enabled
[ 31] [active ] org.forgerock.openidm.error-servlet
[ 163] org.forgerock.openidm.router.servlet enabled
[ 32] [active ] org.forgerock.openidm.router.servlet
[ 165] org.forgerock.openidm.felix.webconsole enabled
[ 196] org.forgerock.openidm.external.email enabled
[ 200] org.forgerock.openidm.servletfilter enabled
[ 200] org.forgerock.openidm.servletfilter.registrator enabled
[ 34] [active ] org.forgerock.openidm.servletfilter.registrator
[ 202] org.forgerock.openidm.schedule enabled
[ 202] org.forgerock.openidm.scheduler enabled
[ 202] org.forgerock.openidm.taskscanner enabled
[ 35] [unsatisfied reference] org.forgerock.openidm.taskscanner
The main cause of this faulty behavior is shown by following line of the output.
Caused by: java.lang.UnsatisfiedLinkError: /tmp/snappy-unknown-f952ea44-7c77-42b0-b2fd-4a3c1540afd8-libsnappyjava.so: Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /tmp/snappy-unknown-f952
What happens is: Version of OrientDB that is currently packaged with OpenIDM (1.7.0) contains mandatory dependency on org.xerial.snappy:snappy-java:1.1.0.1 artifact.
org.forgerock.openidm:openidm-repo-orientdb:bundle:5.5.0-SNAPSHOT
+- com.orientechnologies:orientdb-core:jar:1.7.10:compile
+- org.xerial.snappy:snappy-java:jar:1.1.0.1:compile
In pom.xml of openidm-repo-orientdb module, this dependency is directly overriden by specifiying higher version of the snappy-java:l.1.1.6 (this fact is not important for this issue)..
This dependency is mandatory, which means without it, the orientdb-core bundle cannot be resolved during OSGi init.
The snappy library uses some native pre-compiled code (snappy-java.jar!org/xerial/snappy/native/Linux/x86_64/libsnappyjava.so
) that is packaged with the library and this code fails to load on Alpine Linux because Alpine is musl based distro. Native code in snappy library was compiled and thus is incompatible with musl-based distros (see xerial/snappy-java#181).
Possible solution
I have fiddled with this issue on a 4.0.0 version of OpenIDM codebase a while ago and I was able to make it work by upgrading OrientDB to it's most recent stable version (OrientDB 2.2.22 back then).
You can see changes required for OrientDB upgrade in this commit
This version of OrientDB marks problematic snappy-java as an optional dependency (org.xerial.snappy;resolution:=optional
in OSGi manifest, see module's POM for more detail) so it can be safely excluded on the consumer side (ie. openidm-repo-orientdb module). After upgrading this version of OrientDB, the snappy-java dependency can be safely excluded from classpath and OSGi framework won't complain about missing bundle (we will lose an ability to use compression in OrientDB which is probably fine for evaluation/dev purposes of this storage option).
I would be willing to port these changes to WrenIDM and upgrade OrientDB dependency to its latest version (latest stable is 3.0.2, so that would probably be the target I'll be aiming for) but I'd like to hear your opinion first.
Alternative
According to OpenIDM 5.5.0 release notes, OPENIDM-8861 and OPENIDM-10890, FR has replaced OrientDB with an embedded OpenDJ as a storage backend for product evaluation.
I'd appreciate any opinions and comments on this issue.
Thanks in advance.