ericfaerber.com

Just another WordPress.com site

Using Maven to Create and Install CQ5 Package

Creating components using CRXDE and CRXDE Lite can be frustrating. Both are buggy and are different environments than what you are use to working with. You can use Maven to create a package that it can then install the package in CQ5.

If you have ever extracted a package then you’ll see that there are two folders within it, jcr_root and META-INF. Both of these files are important and they determine how the Maven project should be setup. META-INF holds the filters (paths) that the package contains. jcr_root has all of your files for components, templates, etc. I typically put these files in src/main/content in the Maven project so my code will have that path.

First thing you need to do is in pom.xml under <build> add the following code so that it knows to include your files in the bundle. This also excludes any file vault (VLT) files.

<resources>
    <!-- filter meta information to get some properties into the files -->
    <resource>
        <directory>${basedir}/src/main/content/META-INF</directory>
        <targetPath>META-INF</targetPath>
        <filtering>true</filtering>
    </resource>
    <!-- exclude .vlt control files and tests -->
    <resource>
        <directory>${basedir}/src/main/content/jcr_root</directory>
        <excludes>
            <exclude>**/.vlt</exclude>
            <exclude>**/.vltignore</exclude>
            <exclude>**/.DS_Store</exclude>
        </excludes>
        <targetPath>jcr_root</targetPath>
    </resource>
</resources

Next you need to setup a profile that uses Groovy to install the package to CQ5 using POST.

<profile>
    <id>installUI</id>
    <activation>
        <property>
            <name>installUI</name>
        </property>
    </activation>
    <properties>
        <hostname>http://localhost</hostname>
        <hostport>4502</hostport>
        <publishhostname>http://localhost</publishhostname>
        <publishhostport>4503</publishhostport>
        <packageName>${artifactId}-${version}</packageName>
        <cquser>admin</cquser>
        <cqpassword>admin</cqpassword>
        <showUpload>true</showUpload>
        <showInstall>true</showInstall>
        <projectDir>${basedir}</projectDir>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.gmaven</groupId>
                <artifactId>gmaven-plugin</artifactId>
                <version>1.2</version>
                <dependencies>
                    <dependency>
                        <groupId>org.codehaus.gmaven.runtime</groupId>
                        <artifactId>gmaven-runtime-1.7</artifactId>
                        <version>1.2</version>
                    </dependency>
                    <dependency>
                        <groupId>commons-httpclient</groupId>
                        <artifactId>commons-httpclient</artifactId>
                        <version>3.1</version>
                    </dependency>
                    <dependency>
                        <groupId>commons-logging</groupId>
                        <artifactId>commons-logging</artifactId>
                        <version>1.1.1</version>
                        <type>jar</type>
                        <scope>compile</scope>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <phase>install</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                        <configuration>
                            <defaults>
                                <cqservers>localhost:4502</cqservers>
                                <cquser>admin</cquser>
                                <cqpassword>admin</cqpassword>
                                <packageName>${artifactId}-${version}</packageName>
                                <projectDir>${basedir}</projectDir>
                            </defaults>
                            <source>
                                import org.apache.commons.httpclient.*
                                import org.apache.commons.httpclient.methods.*
                                import org.apache.commons.httpclient.auth.*
                                import org.apache.commons.httpclient.methods.multipart.*

                                //method declaration for execute of PostMethod
                                def executePost(httpclient, httppost, outputResponse){
                                    try {
                                        httpclient.executeMethod(httppost);
                                        if (outputResponse){
                                            println httppost.responseBodyAsString
                                        }
                                    } catch (Exception e) {
                                        println("exception: " + e)
                                    } finally {
                                        httppost.releaseConnection()
                                    }
                                }

                                def uploadAndInstall(hostPort, packageName, projectRoot, httpclient){
                                    //upload package
                                    def httppost = new PostMethod('http://' + hostPort + '/crx/packmgr/service.jsp')
                                    def file = new File(projectRoot + '/target/' + packageName + '.jar')

                                    println("Installing package" +packageName+" to " + hostPort)

                                    if(file.exists()){

                                        def parts = [new FilePart("file", file)] as Part[]
                                        httppost.setRequestEntity(new MultipartRequestEntity(parts,
                                        httppost.getParams()))

                                        executePost(httpclient, httppost, true)

                                        //install package
                                        def installURL = 'http://' + hostPort +
                                        '/crx/packmgr/service/.json/etc/packages/' + packageName + '.zip'
                                        println('INASTALL: ' + installURL)
                                        httppost = new PostMethod(installURL)
                                        httppost.addParameter("cmd", "install")

                                        executePost(httpclient, httppost, true)
                                    } else {
                                        println("File does not exist for " + packageName + ". Not Deploying.")
                                    }
                                }

                                def user = project.properties['cquser']
                                def pass = project.properties['cqpassword']
                                def packageName = project.properties['packageName']
                                def projectRoot = project.properties['projectDir']

                                // set up the client
                                def httpclient = new HttpClient()
                                def defaultcreds = new UsernamePasswordCredentials(user, pass)
                                httpclient.getState().setCredentials(AuthScope.ANY, defaultcreds)
                                httpclient.getParams().setAuthenticationPreemptive(true)

                                println "CQSERVERS:" + project.properties['cqservers']

                                project.properties['cqservers'].tokenize(',').each {
                                    uploadAndInstall(it, packageName, projectRoot, httpclient)
                                }

                            </source>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <!-- Compile Java classes for OSGi bundle -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</profile>

When building the project make sure you select the installUi profile or if you are using the command line add the argument -DinstallUI and it will automatically install the package into CQ5.

I have created a sample project that contains everything you need that you can download here: cq5-sample-ui.zip

Install OSGI Bundles Using Maven

For my job I do a lot of CQ5 work. Often this involves creating OSGI bundles. To install an OSGI bundle you either have to put the bundle in /apps/myproject/install or manually install it in the Felix Web Console. Both of these methods get old after doing it multiple times.

Sling has a Maven plugin that simplifies this process by installing the bundle for you when you build the project. Simply add the following code to your pom.xml file for your Maven project and then select the install-osgi profile when building.

<profile>
	<id>install-osgi</id>
	<activation>
		<property>
			<name>install-osgi</name>
		</property>
	</activation>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.sling</groupId>
				<artifactId>maven-sling-plugin</artifactId>
				<version>2.0.4-incubator</version>
				<executions>
					<execution>
						<id>install-osgi</id>
						<goals>
							<goal>install</goal>
						</goals>
						<configuration>
							<slingUrl>http://localhost:4502/system/console/install</slingUrl>
							<user>admin</user>
							<password>admin</password>
							<skip>false</skip>
							<bundleStartLevel>20</bundleStartLevel>
							<bundleStart>true</bundleStart>
							<refreshPackages>true</refreshPackages>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</profile>

Or if you are using command line to build the project, add -Dinstall-osgi to the arguments. You can create as many profiles as you’d like for the different environments you may be working with (author, publish).

29G planted aquarium background and plan

This is my second attempt at my 29 gallon tank. I didn’t really know what I was doing with my first attempt. I saw some plants at Petco and thought it would be cool to try it. It failed miserably since I didn’t know anything and was trying to learn as I went. I’ve learned that there is lots of work and learning that needs to be done in order to have a planted tank. I need to be patience and learn as much as I can before jumping in with both feet.

I’ve decided to give it a shot again. I’m attempting to do a high tech setup on a budget.

The Details

Substrate: I’m am using a 50/50 mix of flourite and black gravel. It is about 3 inches deep.
Lighting: I have three 8.5 inch clamp lights from Home Depot with 27 watt (or was it 23? I don’t remember) 6500k spiral CFL blubs in them. I write another post explaining my light in more detail.
Filter: I have a SunSun HW-302 canister filter that I plan on using after I fill the tank with water.
CO2: I have a 20# CO2 tank with an Aquatek Regulator and bubble counter. Along with the filter this isn’t being used at the moment since the air contains plenty of CO2 so I don’t need to inject it into the tank.
Fertilizers: I’m still doing research on these but I plan on adding fertilizers once I add water to the tank. I’ll post more about this when I have this figured out.
Plants: I’m going to stick to mostly easy plants and set myself up for success. I’ll throw in a couple harder plants once I get things figured out. I plan to have a heavily planted tank.
Fish: I want some schooling fish for sure. I haven’t thought about this a whole lot since the plants have been my main focus.

Post Navigation

Follow

Get every new post delivered to your Inbox.