Author Archive: Kurt Mossman

OSGi Sling Service Example

I’m posting a simple example of an OSGi Service for Sling. I believe this is enough to get you started with a simple service. First, I want to share a great blog by Moritz Havelock called “In the Sling”. I used this example but changed the file structure of the POM to fit my needs. I’ll be using this as a base for some of my services development. This example is taken from lesson 5.

For my project I’m using Maven 3.0.4, Java 1.6.0_31 and I have tested both CQ 5.4 and CQ 5.5. This should also work fine within Apache Sling but I haven’t tested it.

If you’re like me you just want to get the POM and run it to see if it works for you. First create the file folders based on the structure below. Create 3 Java classes the jsp and a json file. You’ll need to have Maven and Java installed on your system and then just execute the POM.xml with >mvn install

Once the build is completed execute the following URL http://localhost:4502/content/osgitest/test to verify the test. You should see that the service returns “Hello World!”.

I also included a unit test within this example because it’s really easy to create a few tests for the services and if I add it into the example I’m more apt to write a few. To verify that the Unit test works simply change the “Hello World!” to something else and see the failure.

If you’re new to Maven I suggest reading “In the Sling” to really understand what is happening.

│   pom.xml
│
└───src
    ├───main
    │   ├───java
    │   │   └───com
    │   │       └───adobe
    │   │           └───support
    │   │               └───examples
    │   │                   └───osgi
    │   │                       └───service
    │   │                               SampleService.java
    │   │                               SampleServiceImpl.java
    │   │
    │   └───resources
    │       ├───META-INF
    │       └───SLING-INF
    │           └───initial-content
    │               ├───apps
    │               │   └───samples
    │               │       └───osgitest
    │               │               GET.esp
    │               │
    │               └───content
    │                   └───osgitest
    │                           test.json
    │
    └───test
        └───java
                SampleServiceTest.java

<project 	xmlns="http://maven.apache.org/POM/4.0.0" 
			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
			
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.adobe.support.examples</groupId>
	<artifactId>com.adobe.support.examples.osgi.service</artifactId>
	<version>1.0.0</version>
	<packaging>bundle</packaging>
	<name>OSGi Service Example</name>
	<url>http://blogs.adobe.com/kmossman</url>
	<description>Adobe Developer Support OSGi Service Example</description>
	<!--  
	Credit: This example is based on Moritz Havelock's http://in-the-sling.blogspot.com/ 
	
	I suggest you use the most current versions of the plugin's. 
	Search the Central Repository for the most current versions http://search.maven.org/
	
	Use the search strings below and update the appropriate versions
	
	// Felix
	g:"org.apache.felix" a:"org.apache.felix.framework"
	g:"org.apache.felix" a:"maven-bundle-plugin"
	g:"org.apache.felix" a:"maven-scr-plugin"
	g:"org.apache.felix" a:"org.osgi.core"
	// Maven
	g:"org.apache.maven.plugins" a:"maven-compiler-plugin"	
	// Sling
	g:"org.apache.sling" a:"maven-sling-plugin"
	-->
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.build.java.version>1.6</project.build.java.version>
		<!-- Felix -->
		<org.apache.felix.framework.version>4.0.2</org.apache.felix.framework.version> 
    	<org.apache.felix.maven-bundle-plugin.version>2.3.7</org.apache.felix.maven-bundle-plugin.version>    
    	<org.apache.felix.maven-src-plugin.version>1.7.4</org.apache.felix.maven-src-plugin.version>
    	<org.apache.felix.org.osgi.core>1.4.0</org.apache.felix.org.osgi.core>
    	<!-- Maven -->
		<org.apache.maven.plugins.maven-compiler-plugin.version>2.3.2</org.apache.maven.plugins.maven-compiler-plugin.version>
		<org.apache.maven.plugins.maven-surefire-plugin.version>2.12</org.apache.maven.plugins.maven-surefire-plugin.version>
    	<!-- Sling -->
    	<org.apache.sling.maven-sling-plugin.version>2.1.0</org.apache.sling.maven-sling-plugin.version>
  	</properties>
	<build>
	
		<plugins>
			<!--  Maven will compile our source java classes using
			 the "project.build.java.version" specified -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>${org.apache.maven.plugins.maven-compiler-plugin.version}</version>
		        <configuration>
		          <source>${project.build.java.version}</source>
		          <target>${project.build.java.version}</target>
		        </configuration>
			</plugin>
			<!--  this will install the OSGi bundle into Sling for us 
			we now upload the jar file automatically when we build with this plug-in -->
			<plugin>
				<groupId>org.apache.sling</groupId>
				<artifactId>maven-sling-plugin</artifactId>
				<version>${org.apache.sling.maven-sling-plugin.version}</version>
				<executions>
					<execution>
						<id>install-bundle</id>
						<goals>
							<goal>install</goal>
						</goals>
						<configuration>
							<slingUrl>http://localhost:4502/system/console/install</slingUrl>
							<user>admin</user>
							<password>admin</password>
						</configuration>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<!-- This will create the OSGI-INF for us that handles the Activator Class for us
				we now auto-generate the details in our bundle with this plug-in-->
			    <groupId>org.apache.felix</groupId>
			    <artifactId>maven-scr-plugin</artifactId>
			    <extensions>true</extensions>
			    <version>${org.apache.felix.maven-src-plugin.version}</version>
			    <executions>
			        <execution>
			            <id>generate-scr-scrdescriptor</id>
			            <goals>
			                <goal>scr</goal>
			            </goals>
			        </execution>
			    </executions>
			</plugin>			
			<plugin>
				<!-- This will create the OSGi /META-INF/MANIFEST.MF for us
				we now auto-generated the file for us with this plug-in -->
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<extensions>true</extensions>
				<version>${org.apache.felix.maven-bundle-plugin.version}</version>
				<configuration>
					<instructions>
						<Export-Package>com.adobe.support.examples.osgi.service</Export-Package>
						<Import-Package>org.osgi.framework;version="1.3.0"</Import-Package>
						<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
						<Bundle-Name>${project.name}</Bundle-Name>
						<Bundle-Vendor>Kurt Mossman</Bundle-Vendor>
						<!-- 
							Inserting content into the JCR and installing some files on the server with your bundle. 
						
							Sling-Initial-Content
							
								The first line will overwrite the contents of the node at content/osgitest with test.json 
								NOTE: uninstall:=false says that it will not remove the content when I remove the package. 
									This could be set to true to also remove the content when the package is removed the choice is yours. 
								
								The second line will overwrite the path will install the files and overwrite them if you re-install. 
						 -->
						<Sling-Initial-Content>
							SLING-INF/initial-content/content/osgitest;path:=/content/osgitest;overwrite:=true;uninstall:=false,
							SLING-INF/initial-content/apps/samples/osgitest;path:=/apps/samples/osgitest;overwrite:=true;uninstall:=true
						</Sling-Initial-Content>
					</instructions>
				</configuration>
			</plugin>
			<!--  use the surefire plugin to run the test cases
			we use a thread count of 4 to increase the performance of the test time. -->
			<plugin>
			   <groupId>org.apache.maven.plugins</groupId>
			   <artifactId>maven-surefire-plugin</artifactId>
			   <version>${org.apache.maven.plugins.maven-surefire-plugin.version}</version>
			   <configuration>
			     	<parallel>methods</parallel>
			     	<threadCount>4</threadCount>
			   </configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
		  	<groupId>org.apache.felix</groupId>
		  	<artifactId>org.osgi.core</artifactId>
		  	<version>${org.apache.felix.org.osgi.core}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.2</version>
		</dependency>
	</dependencies>
</project>

SampleService.java

package com.adobe.support.examples.osgi.service;

public interface SampleService {
	public String sayHello();
}


SampleServiceImpl.java

package com.adobe.support.examples.osgi.service;

// src.component
// declares the class component. This will provide a wrapped ManagedService component in the OSGI container. 

// src.service interface="SampleService" 
// declares the service we are offering. Actually, the interface attribute is superflous, as by default, all implemented Interfaces are used. 

/**
  @scr.component
  @scr.service interface="SampleService"
 */

public class SampleServiceImpl implements SampleService {
	public String sayHello() {
		return "Hello World!";
	}
}


GET.esp

<%
var service = sling.getService(Packages.com.adobe.support.examples.osgi.service.SampleService);
%>
<br>
The service says: "<%= service.sayHello() %>"


test.json

{
	"jcr:primaryType" : "nt:unstructured",
	"sling:resourceType" : "samples:osgitest"
}


SampleServiceTest.java

import com.adobe.support.examples.osgi.service.SampleService;  
import com.adobe.support.examples.osgi.service.SampleServiceImpl;

import junit.framework.Assert;

import org.junit.Test;

public class SampleServiceTest {
	
	@Test
	public void test() { 
		SampleService ss = new SampleServiceImpl(); 
		String msg = ss.sayHello(); 
		Assert.assertEquals("Hello World!", msg); 
	}
	
}
Share on Facebook

How to search for updated Maven plugin’s? The Central Repository of course!

I have used Maven in the past but I’m no expert. I’m also new to some of the plugin’s used with CQ and I tend to learn best by example so I started looking at all the pom.xml files I could. During my search I found a great example of an OSGi service example called “In the Sling”. The only problem with this example is that it’s an old post and the plugin’s versions are also old in the pom.xml. The information is great and still relevant so I simply needed to update the file with new Maven plugin’s.

The official Maven Central Repository is here: http://search.maven.org 

You can use the advanced search or simply search by Group ID “g:” and Artifact ID “a:” together. This was the quickest way to find the most current version of my plugin’s.

Here are a few examples of how quickly you can retrieve the most current version of a plugin. Just past in the search strings below to get the most current version.

g:”org.apache.felix” a:”maven-bundle-plugin”
g:”org.apache.felix” a:”maven-scr-plugin”
g:”org.apache.maven.plugins” a:”maven-compiler-plugin”
g:”org.apache.sling” a:”maven-sling-plugin”

I added the following within my pom.xml so developers who access my pom.xml files will be able to search quickly for the most current version.

It may seem like a no-brainer but it took me a little while to figure out the most current versions of all the plugin’s for my example.

Share on Facebook

CQ Developer Support a new direction

Over the past five years I have been helping developers with ActionScript and Flex. I just recently moved into a role where I’ll be helping CQ developers and I’m starting to learn the product myself. During my learning process I hope to share some of the issues that are blocking me or just some interesting tips and tricks I find along the way.

Share on Facebook

ADEP Data Services Complete Quick Start

A complete example of using data services with ADEP for Windows. This provides instructions for installing Java, Maven, Flash Builder and ADEP. This contains all the instructions and source code necessary to execute a simple java class example with Flash Builder and Data Services. This information also exists within the ADEP documentation here http://help.adobe.com/en_US/enterpriseplatform/10.0/documentation.html. This document provides you with step-by-step instructions.

Download ADEP Data Services Complete Quick Start

 

Share on Facebook

Flex SDK – running test builds

Setting up a new machine today I ran into an issue running the test command when checking a patch I created for the Flex SDK within ANT.

The command I was running is to test my change: ant -q checkintests

The error was: BUILD FAILED
C:\svn\branches\4.x\build.xml:1103: The following error occurred while executing
this line:
C:\svn\branches\4.x\build.xml:1233: Java returned: 1

This had me confused because I “thought” I had configured everything correctly on this new machine. I checked the build.xml and found it failed on the mustellaresultsparser.

After about 30 minutes of review I realized that I didn’t configure the Flash Player with the mm.cfg for the trace output and looking at the java class for MustellaResultsParser it was clear that it was necessary.

Make sure you have the following lines in your mm.cfg file.
ErrorReportingEnable=1
TraceOutputFileEnable=1

If you run into this error I hope you find my blog ;)

Share on Facebook

Halo Button Skin for Spark Component

Halo Button Skin example

Using Flex 4 and the Spark components you can create a custom SkinClass that looks just like the Halo Flex 3 Button. See the attached example files ButtonSkin.mxml and HaloTheme2.mxml the Button below on the right is a Spark Button and the one on the left is a mx Button.

s|Button
{
skinClass: ClassReference("ButtonSkin");
}

Share on Facebook

LCDS with SSL Termination with Load Balancer fails

If using SSL with a Load Balancer it’s possible you will run into problems trying to reach the LCDS server. The reason for this is caused by the endpoint URL that LCDS is expecting.

This diagram shows a Client Browser request to an HTTPS Load Balancer with SSL Terminiation. Notice that the request is sent from the Load Balancer to the application server with HTTP data.

lb_example.png

Within LCDS most endpoints are servlets within waiting for a request. The messagebroker/amfsecure endpoint is defined within the services-config.xml file for LCDS under the WEB-INF/flex/ directory.

<channel-definition id=”my-amf-secure” class=”mx.messaging.channels.SecureAMFChannel“>
<endpoint url=”https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure” class=”flex.messaging.endpoints.SecureAMFEndpoint “/>
<properties>
<add-no-cache-headers>false</add-no-cache-headers>
</properties>
</channel-definition>

lb_step1.png

Notice in the configuration above we want to send a request from the Client to the Load Balancer as SSL. To do this the SWF uses a channel-definition for SSL. The following class will be used by the SWF to create the channel within ActionScript class=”mx.messaging.channels.SecureAMFChannel“. This will send the request to the Load Balancer where it will terminate the SSL and decrypt it.

The next step in this process is to pass the data from the Load Balancer to the Application server as in the diagram below.

lb_step2.png

On the server we need to modify the endpoint so it will not use a class that tries to decrypt the data. In this case we will use the endpoint class that specifies AMFEndpoint.

<channel-definition id=”my-amf-secure” class=”mx.messaging.channels.SecureAMFChannel“>
<endpoint url=”https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure” class=”flex.messaging.endpoints.AMFEndpoint “/>
<properties>
<add-no-cache-headers>false</add-no-cache-headers>
</properties>
</channel-definition>

With this modification the request is received on the server at the endpoint https://{server.name}:{server.port}{context.root}/messagebroker/amfsecure/ it will use the flex.messaging.endpoints.AMFEndpoint to process the request. This endpoint will not decrypt the data and will pass back the request to the Load Balancer.

Share on Facebook

Adobe AIR 2 Beta 1 apps will not work with AIR 2 beta 2 runtime

Adobe AIR 2 Beta 1 apps will not work with AIR 2 beta 2 runtime

NOTE: Applications built against Adobe AIR 2 beta 1 will not run using the AIR 2 beta 2 runtime. In order for an AIR 2 beta 1 application to run on the AIR 2 beta 2 runtime, the namespace of the beta 1 application descriptor file must first be updated to “2.0beta2″ and compiled against the AIR 2 beta 2 SDK. .

Download the runtime here .

Share on Facebook

Regular expression validator

You may find the need to validate for any regular expression. Here is a simple example of a custom validator where you can add any regular expression to validate. You can set your custom error code.

MXML Source:





ActionScript Class (whiteSpaceValidator.as):


Share on Facebook

Pixel Bender

Pixel Bender will allow you to create some really cool filters, it works with Flash Player 10. Install the Flash Player 10 Beta and Pixel Bender.

Pixel Bender Toolkit

The Flash Blog also has more details. Check out this Flash 10
Tube View.

Share on Facebook