将 Cloudinary 与 Adobe AEM 集成
Integrating Cloudinary with Adobe AEM
我正在尝试将 Adobe AEM 6.3(运行ning on Java 1.8)与 Cloudinary SDK 集成。我已经完成了以下操作,但一直遇到我无法解决的异常。有没有人将 Cloudinary 与 AEM 和 运行 集成到类似的问题中?
- 在
pom.xml
中添加编译代码的依赖。
<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-core</artifactId>
<version>1.24.0</version>
</dependency>
<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-http44</artifactId>
<version>1.24.0</version>
</dependency>
构建 OSGI 插件以确保 AEM 获得正确的 jar 文件。为此,我按照 create a third party RESTful service example 的步骤操作。要构建捆绑包,我必须明确下载以下 jar 文件:cloudinary-1.0.14.jar, cloudinary-core-1.21.0.jar, cloudinary-http44-1.21.0.jar, commons-codec-1.10.jar, commons-collections-3.2.2.jar, commons-lang3-3.1.jar, commons-logging-1.2.jar, httpclient-4.4.jar, httpmime-4.4.jar, jsp-api-2.0.jar
尽管创建了一个包含 httpclient
的包,但在尝试将图像上传到 Cloudinary 时出现以下异常。这是代码和异常。
代码片段
import com.cloudinary.*;
..
Cloudinary cloudinary = new Cloudinary("<<credentials>>");
...
File toUpload = new File("/Users/akshayranganath/Downloads/background-2633962_1280.jpg");
try {
Map uploadResult = cloudinary.uploader().upload(toUpload, ObjectUtils.emptyMap());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
异常
Caused by: java.lang.NoClassDefFoundError: javax/net/ssl/HostnameVerifier
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.defineClass(BundleWiringImpl.java:2370)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2154)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1542)
at org.apache.felix.framework.BundleWiringImpl.access0(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at org.apache.http.impl.conn.SchemeRegistryFactory.createDefault(SchemeRegistryFactory.java:52)
at org.apache.http.impl.client.AbstractHttpClient.createClientConnectionManager(AbstractHttpClient.java:321)
at org.apache.http.impl.client.AbstractHttpClient.getConnectionManager(AbstractHttpClient.java:484)
at org.apache.http.impl.client.AbstractHttpClient.createHttpContext(AbstractHttpClient.java:301)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:818)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
at com.cloudinary.Uploader.callApi(Uploader.java:317)
at com.cloudinary.Uploader.upload(Uploader.java:57)
at com.aem.community.core.models.HelloWorldModel.init(HelloWorldModel.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.sling.models.impl.ModelAdapterFactory.invokePostConstruct(ModelAdapterFactory.java:792)
at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:607)
... 211 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.net.ssl.HostnameVerifier not found by MyBundle [550]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1574)
at org.apache.felix.framework.BundleWiringImpl.access0(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
... 236 common frames omitted
这是我第一次使用 AEM,我可能没有遵循正确的步骤。如果有人能够解决这个问题,请告诉我。
更新
根据 Alexander 的建议和其他来源的指示,我将以下代码添加到父 pom.xml
文件中。
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<instructions>
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Embed-Directory>OSGI-INF/lib</Embed-Directory>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>
进行此更改后,cloudinary 库被添加到捆绑包中。这是 AEM 的输出:http://localhost:4502/system/console/bundles
Embedded-Artifacts: OSGI-INF/lib/cloudinary-http44-1.21.0.jar; g="com.cloudinary"; a="cloudinary-http44"; v="1.21.0", OSGI-INF/lib/commons-lang3-3.1.jar; g="org.apache.commons"; a="commons-lang3"; v="3.1", OSGI-INF/lib/httpclient-4.4.jar; g="org.apache.httpcomponents"; a="httpclient"; v="4.4", OSGI-INF/lib/httpcore-4.4.jar; g="org.apache.httpcomponents"; a="httpcore"; v="4.4", OSGI-INF/lib/commons-logging-1.2.jar; g="commons-logging"; a="commons-logging"; v="1.2", OSGI-INF/lib/commons-codec-1.9.jar; g="commons-codec"; a="commons-codec"; v="1.9", OSGI-INF/lib/httpmime-4.4.jar; g="org.apache.httpcomponents"; a="httpmime"; v="4.4", OSGI-INF/lib/cloudinary-core-1.21.0.jar; g="com.cloudinary"; a="cloudinary-core"; v="1.21.0"
但是,我现在收到一条错误消息:
org.apache.avalon.framework.logger -- Cannot be resolved
org.apache.log -- Cannot be resolved
我可以通过添加依赖项 Avalon framework 来解决 org.apache.avalon.framework.logger
错误。但是,我无法克服 org.apache.log
问题。看来是版本冲突导致了这个问题。
当我为依赖项包含 Cloudinary http44 library. This library doesn't appear to directly reference logging (see here 时,这个新错误开始了)。由于这个错误,应用程序仍然无法从 Installed 状态变为 Active 状态。
Cloudinary-libs 可作为 Maven 工件使用。可以使用 maven-bundle-plugin.
将此类 JAR 文件作为私有库放入您的包中
以下示例适用于我(即使使用 Cloudinary 测试帐户)
...
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<!-- Create the bundle late in the compile-phase instead of the package-phase.
So the generated OSGi meta-data is available during JUnit tests. -->
<id>run-before-tests</id>
<phase>process-classes</phase>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-Name>Test Bundle</Bundle-Name>
<Embed-Dependency>*;groupId=com.cloudinary;scope=compile|runtime</Embed-Dependency>
<Embed-Directory>OSGI-INF/lib</Embed-Directory> <!-- not needed, but nice -->
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>
...
<dependencies>
<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-core</artifactId>
<version>1.24.0</version>
</dependency>
<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-http44</artifactId>
<version>1.24.0</version>
</dependency>
...
一般而言,嵌入外部库可能从简单、繁琐到不可能。这取决于导入工件的依赖项。
手动检查依赖树!(例如https://mvnrepository.com/)
您必须 fiddle 3 条指令:
嵌入依赖
这是放在您的包中的库。小心使用星号运算符,否则您可能会包含太多依赖项(在 AEM 的情况下很容易成为互联网的一半)。但不要包括太少!提取构建的 bundle.jar,以查看实际包含的内容(如果是 cloudinary,则很容易)。
导入包
库通常有太多的依赖关系,特别是如果库来自其他生态系统(如 Spring 或 JEE 容器),或者有很多半可选的依赖关系。使用此设置,您可以告诉 OSGi,可以激活捆绑包,即使某些依赖项不可用。
这是一个真实世界的例子:
<Import-Package>
!com.sun.msv.*,
!org.apache.log4j.jmx.*,
!sun.misc.*,
!org.jboss.logging.*,
!org.apache.zookeeper.*,
*
</Import-Package>
导出包
通常库应该是包私有的。但有时您必须以不同的方式导入,或者库会自动执行某些操作。因此,您应该始终在系统控制台中检查您的包正在导出的内容。如果不正确,您必须使用此设置手动 fiddle:
这是一个例子:
<Export-Package>
!*.internal,
!*.internal.*,
!*.impl,
!*.impl.*,
com.mycompany.myproject.mybundle.*
</Export-Package>
默认情况下导出所有包 *
,除了它们被命名为 impl
或 internal
。他们的子包也是私有的(!*.impl.*
规则)。如果默认设置不起作用,则仅使用此指令导出您需要的内容。
无论您导出什么,都会进入全球 OSGi space。由于 AEM- 和 Sling-Bundle 并不完美,也不是 100% 无错误,请确保
- 开箱即用的 AEM 捆绑包的 startup/shutdown 顺序不应更改
- 代码的部署、重新部署或取消部署不应start/stop任何开箱即用的 AEM 捆绑包。
如果您不确保这一点,您可能会遇到奇怪的部署问题 - 这些问题很难 find/solve。
所以最好不要导出由任何 AEM 开箱即用包导入的任何内容。其他一切仅供专家使用。甚至他们高估了自己,低估了手动修补 AEM 的长期成本。
PS:_removeheaders
指令可以删除运行时不需要的所有 osgi 指令。但只有这样做,如果你想为 public 提供一个包并让它完全闪亮。我会把它留在里面,因为它是某种文档。
我正在尝试将 Adobe AEM 6.3(运行ning on Java 1.8)与 Cloudinary SDK 集成。我已经完成了以下操作,但一直遇到我无法解决的异常。有没有人将 Cloudinary 与 AEM 和 运行 集成到类似的问题中?
- 在
pom.xml
中添加编译代码的依赖。
<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-core</artifactId>
<version>1.24.0</version>
</dependency>
<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-http44</artifactId>
<version>1.24.0</version>
</dependency>
构建 OSGI 插件以确保 AEM 获得正确的 jar 文件。为此,我按照 create a third party RESTful service example 的步骤操作。要构建捆绑包,我必须明确下载以下 jar 文件:
cloudinary-1.0.14.jar, cloudinary-core-1.21.0.jar, cloudinary-http44-1.21.0.jar, commons-codec-1.10.jar, commons-collections-3.2.2.jar, commons-lang3-3.1.jar, commons-logging-1.2.jar, httpclient-4.4.jar, httpmime-4.4.jar, jsp-api-2.0.jar
尽管创建了一个包含
httpclient
的包,但在尝试将图像上传到 Cloudinary 时出现以下异常。这是代码和异常。
代码片段
import com.cloudinary.*;
..
Cloudinary cloudinary = new Cloudinary("<<credentials>>");
...
File toUpload = new File("/Users/akshayranganath/Downloads/background-2633962_1280.jpg");
try {
Map uploadResult = cloudinary.uploader().upload(toUpload, ObjectUtils.emptyMap());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
异常
Caused by: java.lang.NoClassDefFoundError: javax/net/ssl/HostnameVerifier
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.defineClass(BundleWiringImpl.java:2370)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2154)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1542)
at org.apache.felix.framework.BundleWiringImpl.access0(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at org.apache.http.impl.conn.SchemeRegistryFactory.createDefault(SchemeRegistryFactory.java:52)
at org.apache.http.impl.client.AbstractHttpClient.createClientConnectionManager(AbstractHttpClient.java:321)
at org.apache.http.impl.client.AbstractHttpClient.getConnectionManager(AbstractHttpClient.java:484)
at org.apache.http.impl.client.AbstractHttpClient.createHttpContext(AbstractHttpClient.java:301)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:818)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
at com.cloudinary.Uploader.callApi(Uploader.java:317)
at com.cloudinary.Uploader.upload(Uploader.java:57)
at com.aem.community.core.models.HelloWorldModel.init(HelloWorldModel.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.sling.models.impl.ModelAdapterFactory.invokePostConstruct(ModelAdapterFactory.java:792)
at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:607)
... 211 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.net.ssl.HostnameVerifier not found by MyBundle [550]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1574)
at org.apache.felix.framework.BundleWiringImpl.access0(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
... 236 common frames omitted
这是我第一次使用 AEM,我可能没有遵循正确的步骤。如果有人能够解决这个问题,请告诉我。
更新
根据 Alexander 的建议和其他来源的指示,我将以下代码添加到父 pom.xml
文件中。
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<instructions>
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Embed-Directory>OSGI-INF/lib</Embed-Directory>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>
进行此更改后,cloudinary 库被添加到捆绑包中。这是 AEM 的输出:http://localhost:4502/system/console/bundles
Embedded-Artifacts: OSGI-INF/lib/cloudinary-http44-1.21.0.jar; g="com.cloudinary"; a="cloudinary-http44"; v="1.21.0", OSGI-INF/lib/commons-lang3-3.1.jar; g="org.apache.commons"; a="commons-lang3"; v="3.1", OSGI-INF/lib/httpclient-4.4.jar; g="org.apache.httpcomponents"; a="httpclient"; v="4.4", OSGI-INF/lib/httpcore-4.4.jar; g="org.apache.httpcomponents"; a="httpcore"; v="4.4", OSGI-INF/lib/commons-logging-1.2.jar; g="commons-logging"; a="commons-logging"; v="1.2", OSGI-INF/lib/commons-codec-1.9.jar; g="commons-codec"; a="commons-codec"; v="1.9", OSGI-INF/lib/httpmime-4.4.jar; g="org.apache.httpcomponents"; a="httpmime"; v="4.4", OSGI-INF/lib/cloudinary-core-1.21.0.jar; g="com.cloudinary"; a="cloudinary-core"; v="1.21.0"
但是,我现在收到一条错误消息:
org.apache.avalon.framework.logger -- Cannot be resolved
org.apache.log -- Cannot be resolved
我可以通过添加依赖项 Avalon framework 来解决 org.apache.avalon.framework.logger
错误。但是,我无法克服 org.apache.log
问题。看来是版本冲突导致了这个问题。
当我为依赖项包含 Cloudinary http44 library. This library doesn't appear to directly reference logging (see here 时,这个新错误开始了)。由于这个错误,应用程序仍然无法从 Installed 状态变为 Active 状态。
Cloudinary-libs 可作为 Maven 工件使用。可以使用 maven-bundle-plugin.
将此类 JAR 文件作为私有库放入您的包中以下示例适用于我(即使使用 Cloudinary 测试帐户)
...
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<!-- Create the bundle late in the compile-phase instead of the package-phase.
So the generated OSGi meta-data is available during JUnit tests. -->
<id>run-before-tests</id>
<phase>process-classes</phase>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-Name>Test Bundle</Bundle-Name>
<Embed-Dependency>*;groupId=com.cloudinary;scope=compile|runtime</Embed-Dependency>
<Embed-Directory>OSGI-INF/lib</Embed-Directory> <!-- not needed, but nice -->
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>
...
<dependencies>
<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-core</artifactId>
<version>1.24.0</version>
</dependency>
<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-http44</artifactId>
<version>1.24.0</version>
</dependency>
...
一般而言,嵌入外部库可能从简单、繁琐到不可能。这取决于导入工件的依赖项。
手动检查依赖树!(例如https://mvnrepository.com/)
您必须 fiddle 3 条指令:
嵌入依赖
这是放在您的包中的库。小心使用星号运算符,否则您可能会包含太多依赖项(在 AEM 的情况下很容易成为互联网的一半)。但不要包括太少!提取构建的 bundle.jar,以查看实际包含的内容(如果是 cloudinary,则很容易)。
导入包
库通常有太多的依赖关系,特别是如果库来自其他生态系统(如 Spring 或 JEE 容器),或者有很多半可选的依赖关系。使用此设置,您可以告诉 OSGi,可以激活捆绑包,即使某些依赖项不可用。
这是一个真实世界的例子:
<Import-Package>
!com.sun.msv.*,
!org.apache.log4j.jmx.*,
!sun.misc.*,
!org.jboss.logging.*,
!org.apache.zookeeper.*,
*
</Import-Package>
导出包
通常库应该是包私有的。但有时您必须以不同的方式导入,或者库会自动执行某些操作。因此,您应该始终在系统控制台中检查您的包正在导出的内容。如果不正确,您必须使用此设置手动 fiddle:
这是一个例子:
<Export-Package>
!*.internal,
!*.internal.*,
!*.impl,
!*.impl.*,
com.mycompany.myproject.mybundle.*
</Export-Package>
默认情况下导出所有包 *
,除了它们被命名为 impl
或 internal
。他们的子包也是私有的(!*.impl.*
规则)。如果默认设置不起作用,则仅使用此指令导出您需要的内容。
无论您导出什么,都会进入全球 OSGi space。由于 AEM- 和 Sling-Bundle 并不完美,也不是 100% 无错误,请确保
- 开箱即用的 AEM 捆绑包的 startup/shutdown 顺序不应更改
- 代码的部署、重新部署或取消部署不应start/stop任何开箱即用的 AEM 捆绑包。
如果您不确保这一点,您可能会遇到奇怪的部署问题 - 这些问题很难 find/solve。
所以最好不要导出由任何 AEM 开箱即用包导入的任何内容。其他一切仅供专家使用。甚至他们高估了自己,低估了手动修补 AEM 的长期成本。
PS:_removeheaders
指令可以删除运行时不需要的所有 osgi 指令。但只有这样做,如果你想为 public 提供一个包并让它完全闪亮。我会把它留在里面,因为它是某种文档。