<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Function1 &#187; Development</title>
	<atom:link href="http://www.function1.com/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.function1.com</link>
	<description>Discussing all things portal, WebCenter Interaction, WebCenter Suite, Sharepoint, and related technologies.</description>
	<lastBuildDate>Fri, 25 Jun 2010 15:20:23 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Everything Maven Part 2 &#8211; Twitter Portlet</title>
		<link>http://www.function1.com/2010/03/everything-maven-part-2-twitter-portlet/</link>
		<comments>http://www.function1.com/2010/03/everything-maven-part-2-twitter-portlet/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 18:57:05 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Cool Tools]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Portal]]></category>
		<category><![CDATA[Portal Server]]></category>
		<category><![CDATA[idk]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[wci]]></category>
		<category><![CDATA[WebCenter Interaction]]></category>

		<guid isPermaLink="false">http://www.function1.com/?p=773</guid>
		<description><![CDATA[A few weeks ago I wrote about reasons why you might want to invest some time in learning and using maven: &#8220;Everything maven Part I&#8221;. Now it&#8217;s time to roll up our sleeves and get down into guts of maven. In this article, I&#8217;ll describe how you can use Maven to build and deploy a [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago I wrote about reasons why you might want to invest some time in learning and using maven: <a href="http://www.function1.com/2010/02/everything-maven-part-1-is-it-worth-the-effort/">&#8220;Everything maven Part I&#8221;</a>. Now it&#8217;s time to roll up our sleeves and get down into guts of maven. In this article, I&#8217;ll describe how you can use Maven to build and deploy a WCI portlet using the IDK. The portlet will connect to Twitter and return all your followers&#8217; latest tweets.</p>
<h3>Step 1: Install Maven</h3>
<p>Here&#8217;s a link to the <a href="http://maven.apache.org/download.html#Installation">official maven2 installation guide</a>. Here are the steps I used to install on my windows laptop:<span id="more-773"></span></p>
<ul>
<li>Download and install the Sun Java JDK 6 update 18. Here&#8217;s the link: http://java.sun.com/javase/downloads/widget/jdk6.jsp.</li>
<li>Download the latest maven installation zip file from here http://maven.apache.org/download.html</li>
<li>Extract the zip and move &#8216;apache-maven-2.2.1&#8242; into c:/Program Files/Apache Software Foundation/apache-maven-2.2.1</li>
<li>Create a windows environment variable named &#8220;M2_HOME&#8221; and pointed it to the maven installation directory: M2_HOME=c:\Program Files\Apache Software<br />
Foundation\apache-maven-2.2.1</li>
<li>Create a windows environment variable named &#8220;M2_REPO&#8221; and point it to &#8220;C:\Documents And Settings\dave.m2\repository&#8221; (this will make more sense after you read the section below on repositories).</li>
<li>Make sure that the &#8220;JAVA_HOME&#8221; environment variable is set. For example, the JAVA_HOME environment variable on my windows laptop is set to C:\Program Files\Java\jdk1.6.0_18</li>
<li>Add the <code>mvn</code> command to the windows &#8220;PATH&#8221; environment variable like so: PATH=&#8230;;%M2_HOME%\bin</li>
<li>Finally, Test to ensure maven was installed correctly. Open a Windows DOS Command Prompt, and type &#8220;mvn -version&#8221;. If you see the following you should be good to go:<br />
<code>C:\Users\Dave&gt;mvn -version<br />
Apache Maven 2.2.1 (r801777; 2009-08-06 15:16:01-0400)<br />
Java version: 1.6.0_18<br />
Java home: c:\Program Files (x86)\Java\jdk1.6.0_18\jre<br />
Default locale: en_US, platform encoding: Cp1252<br />
OS name: "windows 7" version: "6.1" arch: "x86" Family: "windows"</code></li>
</ul>
<p>Maven is installed. Let&#8217;s take a break, here&#8217;s an airplane landing with one wing:</p>
<p><object width="384" height="313"><param name="movie" value="http://www.youtube.com/v/XZiP4NaeYrE&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/XZiP4NaeYrE&#038;fs=1" type="application/x-shockwave-flash" width="384" height="313" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h3>Step 1b: Get the code</h3>
<p>Here&#8217;s a Zip containing the complete portlet code: <a href='http://www.function1.com/wp-content/uploads/2010/03/function1-twitter-portlet.zip'>function1-twitter-portlet</a>. Feel free to refer to this as I describe the steps to create a maven portlet project below. This zip contains a fully functionaly maven project. Extract the zip and open the pom.xml file. Add your twitter credentials to the file, and then open a command prompt. Change directories to wherever you extracted the zip and then run the following command:</p>
<pre><code>mvn install</code></pre>
<p>If maven is installed correctly, and your twitter credentials are valid, this command should download required jars from maven, run tests to make sure it can connect to twitter, and build a deploy-able portlet war file under directory named &#8216;target&#8217;!</p>
<h3>Step 2: Create Basic pom.xml</h3>
<p>Now that Maven is installed, we need to create an empty Maven Project. A the bare minimum, a Maven Project is nothing more than a folder that contains a single file named &#8216;pom.xml&#8217;. In Maven terminology, &#8220;POM&#8221; stands for &#8220;Project Object Model&#8221;. Maven will look for a pom.xml file to discover everything it needs to know about our Twitter Portlet Java Project. Once you&#8217;ve used Maven for a few different projects, this will become second nature&#8230;I promise. Eventually you&#8217;ll have a template pom.xml that you can simply copy into a new directory each time you&#8217;d like to create a new maven project.</p>
<p>First, we&#8217;ll create a new directory named &#8216;twitter-portlet&#8217; (or just follow along by browsing the code from the zip file). Next, create a new pom.xml file and copy in the following</p>
<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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"&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

  &lt;groupId&gt;com.function1&lt;/groupId&gt;
  &lt;artifactId&gt;wci-twitter-portlet&lt;/artifactId&gt;
  &lt;packaging&gt;war&lt;/packaging&gt;
  &lt;version&gt;0.1&lt;/version&gt;

  &lt;name&gt;WebCenter Interation Twitter Portlet&lt;/name&gt;
&lt;/project&gt;
</code></pre>
<p>So far, we haven&#8217;t done anything more than describe our Twitter Portlet Project to Maven. Here&#8217;s a short overview of each line: </p>
<ul>
<li>The &#8220;modelVersion&#8221; is required by all Maven2 Projects and always has the value 4.0.0.</li>
<li>The &#8220;groupidId&#8221; tells Maven that this project belongs in the &#8220;com.function1&#8243; group. The best practice is to use your company&#8217;s name for the groupid, but it can be whatever you choose. Multiple projects (multiple pom.xml files) can all share the same group id.</li>
<li>The &#8220;artifactId&#8221; defines the name of our specific project: wci-twitter-portlet.</li>
<li>&#8220;packaging&#8221; tells maven what type of project we&#8217;re building. 99% of the time, this is either going to be &#8220;war&#8221; or &#8220;jar&#8221;. In this case, of course, we want a war to deploy as a remote portlet.</li>
<li>The &#8220;version&#8221; tag defines what version of the wci-twitter-portlet we&#8217;re working on. In this case, its the first version ever so I chose to call it version &#8220;0.1&#8243;.</li>
<li>The &#8220;name&#8221; is just a human readable name. Maven will use this when generating documentation.</li>
</ul>
<h3>Step 3: Directory Structure</h3>
<p>Maven is very particular about the directory structure of a project. If this is the first time you&#8217;ve used Maven, this might make you feel a bit trapped. When I first started with Maven I tried to fight it by using my own directory structure. Over time, I&#8217;ve come to see the light. Trust me, just go with it. I&#8217;ve realized that the directory structure used by Maven is a proven best practice and in the end it really makes things consistent and easy. Here&#8217;s what the basic directory structure looks like: </p>
<p><a href="http://www.function1.com/wp-content/uploads/2010/03/twitter-portlet-screenshot4.jpg"><img src="http://www.function1.com/wp-content/uploads/2010/03/twitter-portlet-screenshot4.jpg" alt="" width="154" height="127" class="aligncenter size-full wp-image-788" /></a></p>
<ul>
<li>Create a directory named src/main/java. This is where we will put custom java code.</li>
<li>Next create a directory named src/test/java. This is where unit test code goes.</li>
<li>Now create a directory named src/main/resources. Here&#8217;s were all your configuration files go. For example: DTD, .properties files, xml files (such as log4j.xml), etc.</li>
<li>Finally, create a directory named src/main/webapps. Here&#8217;s where your jsp&#8217;s, and WEB-INF/web.xml file, and any static stuff like images, and javascript.</li>
</ul>
<p>Ok, directory structure is done, Time for a break! I think the things that this guy builds are freaking cool: </p>
<p><object width="384" height="313"><param name="movie" value="http://www.youtube.com/v/WcR7U2tuNoY&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/WcR7U2tuNoY&#038;fs=1" type="application/x-shockwave-flash" width="384" height="313" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h3>Step 4: Generate an Eclipse Project</h3>
<p>By this point, we&#8217;ve given maven enough information to be able to create an Eclipse project for us. switch to your command prompt and run the following command:</p>
<pre><code>mvn eclipse:eclipse</code></pre>
<p>You should see a message &#8220;BUILD SUCCESFUL&#8221;. Open Eclipse and choose &#8220;File -&gt; Import -&gt; Existing Projects into Workspace&#8221;. Choose the twitter-portlet directory and import the wci-twitter-portlet eclipse project (notice Maven used the artifactid for the name of the eclipse project).</p>
<h3>Step 5: IDK and DEPENDENCIES</h3>
<p>Our Twitter Portlet will need to use the IDK to get the current username. We&#8217;ll need to depend on the WCI IDK. So, the next step is to download the IDK (if you haven&#8217;t yet). Once it&#8217;s downloaded, extract the installation zip and then find the WEB-INF directory under idk/10.3.0/devkit. Copy the WEB-INF folder into the wci-twitter-portlet directory into src/main/webapp/.</p>
<p>Now, delete the lib directory! Yep, you heard me. Just like taking off a bandaid, rip that lib directory out of there. After reading this article, you&#8217;ll never have to copy the idk lib directory again (ok, except maybe when they upgrade to 11g). Now it&#8217;s time to tell Maven to manage these jars for us.</p>
<h4>Maven Repositories</h4>
<p>Which leads us to the concept of Maven &#8220;repositories&#8221;. Maven looks for jar dependencies inside repositories. The Maven Book does a much better job at describing the concept than I can, but basically, a repository is simply directory structure containing maven artifacts.</p>
<p>By default, Maven looks first for dependencies here: <a href="http://repo1.maven.org/maven2/">http://repo1.maven.org/maven2/</a></p>
<p>Thanks to convention over configuration, everything inside the repository is organized using the following structure:</p>
<p><code>groupId/artifactId/version/artifactId-version.ext</code></p>
<p>For example, log4j, version 1.2.9 can be found here: </p>
<p><a href="http://repo1.maven.org/maven2/log4j/log4j/1.2.9/">http://repo1.maven.org/maven2/log4j/log4j/1.2.9/</a>. </p>
<p>In this case, groupid and artifactid are both set to &#8216;log4j&#8217;. Here&#8217;s another example, &#8216;axis&#8217; can be found here: </p>
<p><a href="http://repo2.maven.org/maven2/org/apache/axis/axis/1.4/">http://repo2.maven.org/maven2/org/apache/axis/axis/1.4/</a></p>
<p>There are several tools available to help search the maven repository for stuff. There&#8217;s a <a href="http://maven.apache.org/plugins/maven-eclipse-plugin/">Maven-Eclipse plugin</a> that allows you to search and automatically add dedpendencies to a maven project. There&#8217;s also a website that allows you to search the maven repository: <a href="http://mvnrepository.com/">http://mvnrepository.com/</a>. For example, when you do a search for &#8216;log4j&#8217; this site will show you all available versions. If you drill down into version 1.2.15, you&#8217;ll see the following:</p>
<pre><code>&lt;dependency&gt;
    &lt;groupId&gt;log4j&lt;/groupId&gt;
    &lt;artifactId&gt;log4j&lt;/artifactId&gt;
    &lt;version&gt;1.2.15&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
<p>I know, I know, xml makes my eyes glaze over too. To be honest, I&#8217;m not crazy about the fact that maven relies 100% on xml. When you write java code, you gotta deal with xml, what can I say?</p>
<p>So, if we added this snippet of xml to or pom.xml, maven will know that our project uses log4j. In fact, maven will be so nice as to find and download the appropriate log4j jar and make it available on the classpath of our project.</p>
<p>Maven is smart &#8211; as smart as they come. Instead of downloading jars every time you do a build, it only downloads the jars once. And instead of downloading the same jars into every maven project, it downloads them into a directory under your operating system user&#8217;s home directory. For example, on windows, this is C:\Documents and Settings\Dave\.m2\repository. On mac, this is /Users/Dave/.m2/repository.</p>
<p>Ok, that was a lot. Here&#8217;s a quick summary: The Maven repository located at http://repo2.maven.org is a remote repository. When you tell maven that you need log4j by including the xml snippet above, it will first check your local maven repository (which is under your os user&#8217;s home directory). If it can&#8217;t find the jar, it will then check http://repo1.maven.org/maven2/.</p>
<h4>Dealing with IDK Jars</h4>
<p>So, the problem is that none of the idk jars are available in either of those places. To solve this, we&#8217;ll need to copy the idk jars into a local maven repository of some sort.</p>
<p>The first step in doing so, is to re-arrange the jars inside the idk&#8217;s lib directory to match the directory structure that maven expects. Like so:</p>
<p><a href="http://www.function1.com/wp-content/uploads/2010/03/twitter-portlet-screenshot3.jpg"><img src="http://www.function1.com/wp-content/uploads/2010/03/twitter-portlet-screenshot3.jpg" alt="" width="309" height="636" class="aligncenter size-full wp-image-789" /></a></p>
<p>Next, we need to tell Maven to look at our new local directory repository in addition to the default repo at http://repo2.maven.org/maven2. Here&#8217;s the snippet of xml inside pom.xml that does so:</p>
<pre><code>&lt;repositories&gt;
  &lt;repository&gt;
    &lt;id&gt;thirdparty&lt;/id&gt;

    &lt;name&gt;Thirdparty Jars&lt;/name&gt;
    &lt;url&gt;file://${basedir}/thirdparty/m2/repository&lt;/url&gt;
    &lt;layout&gt;default&lt;/layout&gt;
  &lt;/repository&gt;

&lt;/repositories&gt;
</code></pre>
<p>Now that the idk dependencies are available, lets add them to our project. We&#8217;re going to add a snippet of xml for each jar. Here&#8217;s a few examples to give you an idea:</p>
<pre><code> &lt;dependencies&gt;
   &lt;dependency&gt;

     &lt;groupId&gt;com.oracle.idk&lt;/groupId&gt;
     &lt;artifactId&gt;activation&lt;/artifactId&gt;
     &lt;version&gt;10.3&lt;/version&gt;
  &lt;/dependency&gt;

  &lt;dependency&gt;
    &lt;groupId&gt;com.oracle.idk&lt;/groupId&gt;
    &lt;artifactId&gt;axis&lt;/artifactId&gt;
    &lt;version&gt;10.3&lt;/version&gt;

  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;com.oracle.idk&lt;/groupId&gt;
    &lt;artifactId&gt;commons-discovery&lt;/artifactId&gt;
    &lt;version&gt;10.3&lt;/version&gt;

  &lt;/dependency&gt;
... more depenedencies ...
&lt;/dependencies&gt;
</code></pre>
<p>Phwew! We&#8217;re getting to the end&#8230;before we do, here&#8217;s a old spice commercial that cracks me up:</p>
<p><object width="500" height="306"><param name="movie" value="http://www.youtube.com/v/owGykVbfgUE&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/owGykVbfgUE&#038;fs=1" type="application/x-shockwave-flash" width="500" height="306" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h3>Step 6: Write the Code!</h3>
<p>At this point, we have everything to need to create a portlet that uses the IDK. Please take a look inside the zip to see the code. But why stop there? Let&#8217;s add some twitter! It just so happens that there&#8217;s a library called twitter4j available via maven:</p>
<pre><code>    &lt;dependency&gt;
      &lt;groupId&gt;org.twitter4j&lt;/groupId&gt;
      &lt;artifactId&gt;twitter4j-core&lt;/artifactId&gt;
      &lt;version&gt;2.1.0&lt;/version&gt;

    &lt;/dependency&gt;
</code></pre>
<p>Run <code>mvn eclipse:eclipse</code> again to update your eclipse project with the new twitter4j jar. (If Eclipse is open while you run this command, remember to do a &#8220;refresh&#8221; in Eclipse so that Eclipse see&#8217;s the new jar)</p>
<p>Now, we can add some code to our portlet that uses twitter4j to retrieve the latest status from each twitter friend. Here&#8217;s the relevant snippet. Feel free to peruse the full source int he zip file: </p>
<pre><code> public List&lt;String&gt; getFriendsMostRecentTweet() {
    List&lt;String&gt; tweets = new ArrayList&lt;String&gt;();
    String senderID = getTwitterLogin();
    String senderPassword = getTwitterPassword(); 

    Twitter twitter = new TwitterFactory().getInstance(senderID,
            senderPassword);
    PagableResponseList&lt;User&gt; statuses;
    try {
        statuses = twitter.getFriendsStatuses();
        for (User nextTwitterUser : statuses) {
            tweets.add(nextTwitterUser.getName() + ": "
                    + nextTwitterUser.getStatusText());
        }
    } catch (TwitterException e) {
        System.out.println("Unable to retrieve tweets");
        return null;
    }
    return tweets;
}

</code></pre>
<p>Finally: Running the command &#8220;mvn install&#8221; will create a war file named wci-twitter-portlet-0.1.war under the target directory. Deploy that war to tomcat (or weblogic or whatever you&#8217;re using as a remote java portal server). Create the remote server, webservice, and portlet objects inside the WCI Portlet and marvel at the twitter messages!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.function1.com/2010/03/everything-maven-part-2-twitter-portlet/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Real World Example of PT Tags</title>
		<link>http://www.function1.com/2010/03/a-real-world-example-of-pt-tags/</link>
		<comments>http://www.function1.com/2010/03/a-real-world-example-of-pt-tags/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 21:00:54 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Portal]]></category>
		<category><![CDATA[Aqualogic]]></category>
		<category><![CDATA[communityactionsdata]]></category>
		<category><![CDATA[mandtabcommsdata]]></category>
		<category><![CDATA[mycommunitiesdata]]></category>
		<category><![CDATA[PT Tags]]></category>
		<category><![CDATA[pt.data]]></category>
		<category><![CDATA[wci]]></category>
		<category><![CDATA[WebCenter Interaction]]></category>

		<guid isPermaLink="false">http://www.function1.com/?p=718</guid>
		<description><![CDATA[If Aqualogic PT Tags were a character on MTVs Real World, it would surely be the difficult to understand, moody, and unpredictable one. Part of the misunderstanding comes from the cryptic tag library documentation and general lack of real world examples.
PT Tags give you the ability to use out-of-the-box coding logic within simple HTML pages. With a little [...]]]></description>
			<content:encoded><![CDATA[<p>If Aqualogic <a title="PT Tag Reference Guide" href="http://download.oracle.com/docs/cd/E13158_01/alui/wci/docs103/devguide/apidocs/tagdocs/index.html">PT Tags</a> were a character on MTVs Real World, it would surely be the difficult to understand, moody, and unpredictable one. Part of the misunderstanding comes from the cryptic <a href="http://download.oracle.com/docs/cd/E13158_01/alui/wci/docs103/devguide/apidocs/tagdocs/index.html">tag library documentation</a> and general lack of real world examples.</p>
<p>PT Tags give you the ability to use out-of-the-box coding logic within simple HTML pages. With a little patience and a slightly different way of thinking about logic flow, PT Tags can be an inexpensive answer to your UI problem.</p>
<p>Function1 has been &#8220;roomies&#8221; with PT Tags for quite some time, and we love our often confusing friend. To help educate our readers on PT Tags, here&#8217;s an example of solving a joined communities tag problem for portal navigation.</p>
<p><span id="more-718"></span></p>
<p>The &lt;pt:ptdata.mycommunitiesdata/&gt; tag is a useful array to get all the communities for your portal installation. However the tag includes both joined and mandatory communities for a user. Recently, a customer asked us to remove mandatory and mandatory with tab communities so the navigation could be seperated. How? we thought.</p>
<p>The solution is to use a different list of data from &lt;pt:data.mandtabcommsdata /&gt;. This tag contains an array of mandatory with tab communities. Our thought process was to loop through the communities data and compare it to a continuous loop of mandatory tab data. Whenever a link was found that did not have a matching mandatory link, we printed it as a joined community.</p>
<div style="font-size: 11px">&lt;pt:core.comment&gt;&lt;!&#8211; ##### Data used to determine correct tags ##### &#8211;&gt;&lt;/pt:core.comment&gt;<br />
&lt;pt:ptdata.mycommunitiesdata pt:id=&#8221;commLinks&#8221; /&gt;<br />
&lt;pt:ptdata.mandtabcommsdata pt:id=&#8221;mandComms&#8221; /&gt;<br />
&lt;pt:ptdata.communityactionsdata pt:id=&#8221;commActionLinks&#8221; /&gt;<br />
&lt;pt:core.comment&gt;&lt;!&#8211; ################################################&#8211;&gt;&lt;/pt:core.comment&gt;<br />
&lt;!&#8211; loop through all the community data which includes both joined and mandatory communities &#8211;&gt;<br />
&lt;pt:logic.foreach pt:data=&#8221;commLinks&#8221; pt:var=&#8221;currComm&#8221;&gt;<br />
&lt;pt:logic.variable pt:key=&#8221;isMandatory&#8221; pt:value=&#8221;0&#8243;/&gt;<br />
&lt;!&#8211; loop through all mandatory with tab communities and compare against the current joined community &#8211;&gt;<br />
&lt;pt:logic.foreach pt:data=&#8221;mandComms&#8221; pt:var=&#8221;currMandComm&#8221;&gt;<br />
&lt;pt:logic.intexpr pt:expr=&#8221;($isMandatory) == 0&#8243; pt:key=&#8221;boolJoinedCheck&#8221;/&gt;<br />
&lt;pt:logic.if pt:expr=&#8221;$boolJoinedCheck&#8221;&gt;<br />
&lt;pt:logic.iftrue&gt;<br />
&lt;pt:logic.intexpr pt:expr=&#8221;($currComm.objid) == ($currMandComm.objid)&#8221; pt:key=&#8221;boolMandatoryCheck&#8221;/&gt;<br />
&lt;pt:logic.if pt:expr=&#8221;$boolMandatoryCheck&#8221;&gt;<br />
&lt;pt:logic.iftrue&gt;<br />
&lt;pt:logic.variable pt:key=&#8221;isMandatory&#8221; pt:value=&#8221;1&#8243;/&gt;<br />
&lt;/pt:logic.iftrue&gt;<br />
&lt;/pt:logic.if&gt;<br />
&lt;/pt:logic.iftrue&gt;<br />
&lt;/pt:logic.if&gt;<br />
&lt;/pt:logic.foreach&gt;<br />
&lt;!&#8211; print only the joined communities &#8211;&gt;<br />
&lt;pt:logic.intexpr pt:expr=&#8221;($isMandatory) == 0&#8243; pt:key=&#8221;boolJoinedCheck&#8221;/&gt;<br />
&lt;pt:logic.if pt:expr=&#8221;$boolJoinedCheck&#8221;&gt;<br />
&lt;pt:logic.iftrue&gt;<br />
&lt;!&#8211; TO CHANGE JOINED LINKS STYLE ADD A ATTRIBUTE TO THIS LINE &#8211;&gt;<br />
&lt;!&#8211; _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ &#8211;&gt;<br />
&lt;pt:core.html pt:tag=&#8221;a&#8221; href=&#8221;$currComm.url&#8221;&gt;&lt;pt:logic.value pt:value=&#8221;$currComm.title&#8221;/&gt;&lt;/pt:core.html&gt;<br />
&lt;!&#8211; _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ &#8211;&gt;<br />
&lt;/pt:logic.iftrue&gt;<br />
&lt;/pt:logic.if&gt;<br />
&lt;/pt:logic.foreach&gt;</div>
<p> </p>
<p>Those mandatory tab communities might still be needed elsewhere. The following logic first checks if there are any mandatory communities, then loops through all communities and prints a nice link. You can include any css on these links simply by adding the class attribute to the &lt;pt:core.html/&gt; tag.</p>
<div style="font-size: 11px">&lt;pt:logic.existexpr pt:data=&#8221;mandComms&#8221; pt:key=&#8221;hasMandLinks&#8221;/&gt;<br />
&lt;pt:logic.if pt:expr=&#8221;$hasMandLinks&#8221;&gt;<br />
&lt;pt:logic.iftrue&gt;&lt;pt:ptdata.mandatorylinknamedata pt:key=&#8221;mandLinksTabName&#8221; /&gt;<br />
&lt;pt:logic.foreach pt:data=&#8221;mandComms&#8221; pt:var=&#8221;link&#8221;&gt;<br />
&lt;!&#8211; TO CHANGE MANDATORY LINKS STYLE ADD A ATTRIBUTE TO THIS LINE &#8211;&gt;<br />
&lt;!&#8211; _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ &#8211;&gt;<br />
&lt;pt:core.html pt:tag=&#8221;a&#8221; href=&#8221;$link.url&#8221;&gt;&lt;pt:logic.value pt:value=&#8221;$link.title&#8221; /&gt;&lt;/pt:core.html&gt;<br />
&lt;!&#8211; _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ &#8211;&gt;<br />
&lt;/pt:logic.foreach&gt;&lt;/pt:logic.iftrue&gt;<br />
&lt;/pt:logic.if&gt;</div>
<div style="font-size: 11px"> </div>
<p>Finally, administrators and community managers might need to edit their communities just like the out-of-the-box navigation. The following logic will print any additional buttons such as &#8220;manage communities&#8221;.</p>
<div style="font-size: 11px">&lt;pt:core.comment&gt;&lt;!&#8211; Print all the community actions buttons underneath the mandatory links &#8211;&gt;&lt;/pt:core.comment&gt;<br />
&lt;pt:logic.existexpr pt:data=&#8221;commActionLinks&#8221; pt:key=&#8221;hasCommActionLinks&#8221;/&gt;<br />
&lt;pt:logic.if pt:expr=&#8221;$hasCommActionLinks&#8221;&gt;<br />
&lt;pt:logic.iftrue&gt;<br />
&lt;pt:ptdata.joincommunitiesdata pt:id=&#8221;commActionsToDisplay&#8221; /&gt;&lt;pt:logic.foreach pt:data=&#8221;commActionsToDisplay&#8221; pt:var=&#8221;link&#8221;&gt;<br />
&lt;!&#8211; TO CHANGE ACTION LINKS STYLE ADD A ATTRIBUTE TO THIS LINE &#8211;&gt;<br />
&lt;!&#8211; _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ &#8211;&gt;<br />
&lt;pt:core.html pt:tag=&#8221;a&#8221; href=&#8221;$link.url&#8221;&gt;Manage my Communities&lt;/pt:core.html&gt;<br />
&lt;!&#8211; _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ &#8211;&gt;&lt;/pt:logic.foreach&gt;&lt;/pt:logic.iftrue&gt;<br />
&lt;/pt:logic.if&gt;</div>
<p><strong><a href="http://www.function1.com/?attachment_id=734">DOWNLOAD THE FULL CODE HERE</a></strong></p>
<p>We&#8217;ve noticed that we spend so much time with Aqualogic that we think <a title="PT Tag Reference Guide" href="http://download.oracle.com/docs/cd/E13158_01/alui/wci/docs103/devguide/apidocs/tagdocs/index.html">PT Tags</a> is a person. Since it doesn&#8217;t really have a face, we&#8217;ve decided it would probably look a lot like Puck from MTV&#8217;s Real World.</p>
<p style="text-align: center"><a href="http://www.function1.com/wp-content/uploads/2011/03/E_Puck_1361.jpg"><img class="size-full wp-image-720 alignnone" src="http://www.function1.com/wp-content/uploads/2011/03/E_Puck_1361.jpg" alt="" width="136" height="136" /></a></p>
<p style="text-align: center"> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.function1.com/2010/03/a-real-world-example-of-pt-tags/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Everything Maven Part 1 &#8211; Is it Worth the Effort?</title>
		<link>http://www.function1.com/2010/02/everything-maven-part-1-is-it-worth-the-effort/</link>
		<comments>http://www.function1.com/2010/02/everything-maven-part-1-is-it-worth-the-effort/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 21:09:06 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Cool Tools]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[F1 Product]]></category>
		<category><![CDATA[Products]]></category>

		<guid isPermaLink="false">http://www.function1.com/?p=673</guid>
		<description><![CDATA[Each time you write a new Java portlet you may have noticed that there is definitely a set of common steps that need to be completed. For example, even though the functionality of portlets may be completely different, you can always be sure that you&#8217;ll have to do things like setting up a classpath, configuring [...]]]></description>
			<content:encoded><![CDATA[<p>Each time you write a new Java portlet you may have noticed that there is definitely a set of common steps that need to be completed. For example, even though the functionality of portlets may be completely different, you can always be sure that you&#8217;ll have to do things like setting up a classpath, configuring an IDE, hunting around for third party dependencies, testing and debugging, deploying your code to a server, etc. As you may know, there are several software development tools available that claim to help reduce the amount of these tedious &#8220;housekeeping&#8221; tasks. These types of tools are generally referred to as &#8220;Build Systems&#8221;. And the number one Google result for &#8220;Build System&#8221; at the time of this writing is a solution called <a href="http://maven.apache.org/what-is-maven.html">&#8220;Maven&#8221;</a>.</p>
<p>If you peruse maven articles out in the blog-o-sphere, this is the message you&#8217;ll hear: </p>
<blockquote><p>Using Maven will make you a better developer. Using Maven will make your organization more productive. Maven will solve your integration issues. Maven encourages unit testing. Maven will enforce <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> best practices and <a href="http://en.wikipedia.org/wiki/Convention_over_configuration">Convention over Configuration</a>. Maven will save the rainforest and will give you thick, shiny, lustrous hair. Marcia, Marcia, Marcia! &#8230; Maven, Maven, Maven!</p></blockquote>
<p><span id="more-673"></span></p>
<p>You (or your software dev team) might have already written quite a bit of java web apps and have managed to get by pretty well without Maven. You may have even written some killer java portal apps which your organization can&#8217;t live without.  </p>
<p>If you&#8217;re like me, you&#8217;re also probably a bit tired of learning scripting languages (ant, perl, make, bash, dos, ruby, on and on, and on). You&#8217;re probably hesitant to make the investment in learning another. Well, I hear you. I feel your pain. So, in this article, I&#8217;d like to give you some idea about what types of tedious tasks that Maven can help you eliminate (and by doing so, possibly save significant development cost). I also want to try to convince you that Maven is worth the effort. Stay tuned for later articles where I will dive deeper into the actual implementation details of how to best use Maven to manage your java projects. </p>
<p>So, to prove it to you that Maven is well worth the investment, I&#8217;ll walk you through a recent experience. As a new employee at Function1, I am very excited about the product suite currently in development. In particular, I wanted to help add some functionality to one of our new products named Formbuilder.</p>
<p>Remember Studio Server? You know, the one with the <a href="http://www.function1.com/2007/03/tetris-anyone/">Tetris Easter Egg</a>? Well, Formbuilder is everything Studio Server was, plus an easier to use interface and updated with the latest and greatest technologies. Formbuilder really makes it a no-brainer to create and administer surveys and polls. Formbuilder can be run as a standalone webapp inside any of the standard java web containers. It can also be installed to run as a portlet with tight integration with Web Center Interaction.</p>
<p>Here are the steps it took me (as a brand new F1 employee, totally unfamiliar with Formbuilder source code) to get to the point where I could compile and run Formbuilder in a development environment without Maven. Afterwards, I&#8217;ll compare how each step might have been accomplished using Maven. And you can be the judge ;-)</p>
<p>Formbuilder is a standard java web application. On the back end, it uses servlets to manage requests. The servlets talk to a service layer powered by hibernate that manages persisting and retrieving data to database. On the front end, it uses GWT and Ext-JS to provide the views. Administrators can create surveys (using a very slick and easy-to-use user interface, imo):</p>
<div><a href="http://www.function1.com/wp-content/uploads/2010/02/admin32.jpg"><img class="aligncenter size-full wp-image-683" src="http://www.function1.com/wp-content/uploads/2010/02/admin32.jpg" alt="Formbuilder Admin Page" width="645" height="357" /></a></div>
<p>And, of course, Formbuilder also provides a page where you can complete and submit surveys:</p>
<div><a href="http://www.function1.com/wp-content/uploads/2010/02/formbuilder1.jpg"><img class="aligncenter size-full wp-image-684" src="http://www.function1.com/wp-content/uploads/2010/02/formbuilder1.jpg" alt="Formbuilder Example Survey" width="534" height="459" /></a></div>
<p>When I first got a hold of the source code, I was really impressed how well everything was organized. The folder structure followed the normal java development best practices and coding conventions. There were no surprises from a software development point of view.  Even so, getting to the point where I could actually write code, was pretty slow going. If you&#8217;ve ever inherited a non-trivial java application to maintain, I&#8217;m sure you can relate. And in my experience, this &#8220;ramp up&#8221; time is generally accepted by most development teams as something that you &#8220;just have to roll up your sleeves and get done&#8221;. Here are the steps that were necessary for me to get from having zero knowlege of source code to where I was able to compile and run the Formbuilder application:</p>
<h3>Check Out Source Code</h3>
<p>The first step was to get the source code. A few emails and I had access to subversion and I was able to check out the latest and greatest using the svn command line tool.</p>
<h3>Create Eclipse Project</h3>
<p>Eclipse stores info about what it thinks are java projects under a file called &#8220;.project&#8221; and a folder named &#8220;.settings&#8221;. Since these had been checked into subversion, I was able to import the code directly into eclipse as an eclipse java project. Unfortunately, this only kinda-sorta worked. Since the eclipse project had been build on another machine, the Eclipse files contained hard coded paths. There were red X&#8217;s everywhere and Eclipse was not happy.</p>
<h3>Resolved Dependencies</h3>
<p>One of the biggest hassles working with Java is managing the thirdparty jars that each web app depends on. In this case, it was easy to see that all required jars were inside the war/WEB-INF/lib directory. However, I also noticed that all these jars had been checked into source control. For small to medium sized projects, checking jars into source control works ok. But, in my experience, as the source code grows so does the jar dependencies and pretty soon the number of jars becomes unmanageable. Checkouts from svn can quickly become excruciatingly slow. In this case, it wasn&#8217;t a big problem (but something to keep in mind for future maven articles :). I manually added each jar to the eclipse project&#8217;s build path and that made Eclipse a little happier, making a lot of the existing red X&#8217;s go away.</p>
<h3>Compiling the UI Code</h3>
<p>Google Web Toolkit (GWT) is a technology that allows you to write java and have it compiled into javascript. Formbuilder uses GWT to create some really slick web user interfaces. So, the next step was to download and install the Eclipse GWT plugin. This plugin handles all the configuration necessary to be able to &#8220;compile&#8221; gwt java code. After setting up the plugin, eclipse was 100% happy, all the compile errors (Red X&#8217;s) in eclipse were satisfied!</p>
<h3>Build Database</h3>
<p>So now it&#8217;s time to fire this bad boy up and try it out?! Oh right, I probably need to install a database. Some hunting and I found the hibernate.cfg.xml which contained the database credentials. I noticed there were 3 database flavor&#8217;s configured inside of the xml file. Two of the configurations were commented out. I learned that Formbuilder is compatible with serveral database vendors including MySql, Oracle, and Microsoft SQL Server. I chose to use MySql since it lends itself well for development. A few google searches later and I was able to use the mysql command line tool to create a new mysql database (and new mysql user) to match the credentials found in the hibernate config file. I then used the hibernate hbm2ddl tool to automatically generate the datbase schema based on annotations inside the source code. Very cool. Life was good.</p>
<h3>Package</h3>
<p>Okie-Dokie. Things are compiling. The database is created and is online. The next step is to build a war and then test. I found a helpful shell script (named deploy.sh) that bundled up all the compiled class files created by eclipse along with the WEB-INF directory (including all the jars) into a war file. I copied the war file into tomcat/webapps and pointed my browser to browse to http://localhost:8080/formbuilder and voila? Oh, Dag nabbit!</p>
<h3>Runtime Error #1</h3>
<p>From the stack trace, it looked like the servlet was not able to connect to the database. After some more hunting I found that there were several application properties files. One property file was used to build a war to run on a local development environment. Another properties file was used to build a war to run on a production server. The production properties file was &#8220;active&#8221; so I switched back to the local properties file. Ok, run deploy.sh again. Then copy the war over to tomcat/webapps again. Browse to the formbuilder page, and &#8230;. DOH!</p>
<h3>Runtime Error #2</h3>
<p>I was seeing the same database connection error. After some troubleshooting, this time it turned out to be that some of the values inside the properties files were overwriting some of the<br />
values inside hibernate.cfg.xml. I could see that this was intentional. This way, the deploy.sh script could easily switch back and forth between building war for development vs a war for production. Run deploy.sh again, then copy the war over (&#8230;<em>again</em>!).</p>
<h3>Runtime Errors #3-15</h3>
<p>I was now able to connect to the database. But the next errors were several runtime ClassNotFound errors. Even though I had copied all jars over from WEB-INF/libs, it turned out that I needed to find and download a few extra from various web sites. It turned out that I was using a different version of Tomcat than other developers. So I ran the bash script to create the war (&#8230;<em>again</em>!). Then, I manually copied and pasted the war into tomcat/webapps (&#8230;<em>again</em>!).</p>
<h3>Run!</h3>
<p>Finally! Formbuilder was running inside tomcat. I was able to create and save a new survey successfully. All in all, it took probably close to 20 hrs to get to the point where I could start being productive and writing code. </p>
<h3>Maven</h3>
<p>Now, I&#8217;d like to describe the steps it took me to get up and running after I &#8220;mavenized&#8221; the formbuilder project. You ready for this?</p>
<p><strong>c:\&gt; mvn install</strong></p>
<p>That&#8217;s it! No lie. That single command (1) resolves and downloads required thirdparty jars (2) compiles java to class files (3) compiles gwt java to javascript (4) generates the database schema (5) runs junit tests (6) creates a war (7) and actually starts an embedded tomcat server which runs the Formbuilder web app.</p>
<h3>I&#8217;m convinced. So What Next?</h3>
<p>None of the steps described above will come to a surprise to anyone who&#8217;s ever written a Java web application. It can be frustrating (and costly) to manually repeat the same housekeeping tasks over and over. Maven solves this problem by forcing you to organize all your Java projects exactly the same. It gives you a common set of commands for building Java applications. Think how great it would be to be able to run &#8220;<strong>mvn install</strong>&#8221; against any piece of source code that can be found in your organization and have it handle all the tediousness for you?! Automation is a beautiful thing. </p>
<p>Stay tuned for Part II where I&#8217;ll cover more on exactly which common development problems that Maven solves and specifics of how to configure Maven to do so. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.function1.com/2010/02/everything-maven-part-1-is-it-worth-the-effort/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Integrating a Google Web Toolkit application with WCI and the imageserver</title>
		<link>http://www.function1.com/2009/12/integrating-a-google-web-toolkit-application-with-wci-and-the-imageserver/</link>
		<comments>http://www.function1.com/2009/12/integrating-a-google-web-toolkit-application-with-wci-and-the-imageserver/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 18:35:27 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[google web toolkit]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[Portal]]></category>
		<category><![CDATA[wci]]></category>

		<guid isPermaLink="false">http://wp.function1.server296.com/?p=429</guid>
		<description><![CDATA[Google Web Toolkit (GWT) is an open-source web development toolkit that facilitates building rich, Javascript-based applications entirely through Java coding.  It is very useful in speeding up complex application development, as well as in multi-developer projects where Java’s static typing enforces convention across the board.  Function1 has employed GWT in the development of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/webtoolkit/">Google Web Toolkit</a> (GWT) is an open-source web development toolkit that facilitates building rich, Javascript-based applications entirely through Java coding.  It is very useful in speeding up complex application development, as well as in multi-developer projects where Java’s static typing enforces convention across the board.  Function1 has employed GWT in the development of its product line and on the client site.</p>
<p>A GWT application code consists of the generated GWT static resource files (HTML, Javascript, and CSS) on the front end, and server-side service code on the middle and back end.  For performance reasons, static resource files are often deployed to the image server.  And <a href="http://code.google.com/webtoolkit/doc/1.6/FAQ_DebuggingAndCompiling.html#How_do_I_change_the_location_of_my_cache/nocache_HTML_files?">as of version 1.6, Google Web Toolkit easily allows for seamlessly changing the location of the generated GWT static resource files</a> from the default location in the war deployment.</p>
<p>If you do wish to pursue separating the generated static resources from the backing server code, there are a few steps to take.  The primary reason for this change is to avoid potential cross-domain issues that will arise from separating your resources; your imageserver may be running on imageserver.domain.com:80, while your application service might be running on appserver.domain.com:7001.</p>
<p><span id="more-429"></span></p>
<p>For this example, we’ll assume your application is called <em>formbuilder</em>.</p>
<ul>
<li>Under the <em>war</em> folder that GWT generates, you will find a folder with your application name, <em>formbuilder</em>.  Copy that folder to a target folder on the image server, such as /imageserver/RemoteGadgets/formbuilder/gwt/.</li>
<li>On the GWT entry point JSP page, you’ll make two changes.  The first is to create a Javascript variable that stores the gatewayed URL of the servlet.  The second is to change the GWT entry point Javascript reference.</li>
</ul>
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img class="mt-image-none" src="http://www.function1.com/site/GWT%20portlet%20before.png" alt="GWT portlet before.png" width="603" height="560" /></span></p>
<ul>
<li>After the changes, your JSP will look something like the screenshot below.</li>
</ul>
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img class="mt-image-none" src="http://www.function1.com/site/GWT%20portlet%20after.png" alt="GWT portlet after.png" width="603" height="560" /></span></p>
<ul>
<li>Finally, in the Java class that implements the EntryPoint interface, you will reference the gatewayed service URL using GWT’s <a href="http://code.google.com/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideJavaScriptNativeInterface">Javascript Native Interface</a> (JNSI).</li>
</ul>
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img class="mt-image-none" src="http://www.function1.com/site/FormBuilderApp.png" alt="FormBuilderApp.png" width="597" height="753" /></span></p>
<hr />
<p>Bonus tip: As discussed earlier in this post, Google Web Toolkit provides tools to create rich, complex web applications entirely through Java code.  GWT was built with cross-browser compatibility in mind, but not all generated HTML is treated equally.   For example, adding a widget that generates a block level element into a container that generates an inline element may result in an “Error: Invalid source HTML for this operation.” error in Internet Explorer.  When building in GWT, remember that while you are coding in Java, your output is HTML + CSS + Javascript.  As with any web application, be sure to test your GWT app in a variety of browsers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.function1.com/2009/12/integrating-a-google-web-toolkit-application-with-wci-and-the-imageserver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Import Content into Publisher</title>
		<link>http://www.function1.com/2009/04/import-content-into-publisher/</link>
		<comments>http://www.function1.com/2009/04/import-content-into-publisher/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 20:57:57 +0000</pubDate>
		<dc:creator>Hani Atalla</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Publisher]]></category>
		<category><![CDATA[Quick Code]]></category>

		<guid isPermaLink="false">http://wp.function1.com/index.php/262/uncategorized/import-content-into-publisher</guid>
		<description><![CDATA[These are exciting times with Aqualogic (ALI) and its direction as a Portal technology after Oracle&#8217;s acquisition of BEA Systems.&#160; Some of our ALI clients have decided to migrate off ALI&#8217;s Content Management System (CMS), Publisher, and adopt a different platform; e.g. Adobe Contribute. While others are embracing the new Portal CMS Web Center Interaction [...]]]></description>
			<content:encoded><![CDATA[<p>These are exciting times with Aqualogic (ALI) and its direction as a Portal technology after Oracle&#8217;s acquisition of BEA Systems.&nbsp; Some of our ALI clients have decided to migrate off ALI&#8217;s Content Management System (CMS), Publisher, and adopt a different platform; e.g. <a href="http://www.adobe.com/products/contribute/"><u>Adobe Contribute</u></a>. While others are embracing the new Portal CMS Web Center Interaction stack, more specifically, Universal Content Management (UCM) as a Publisher alternative as they migrate from their existing CMS; e.g. <a href="http://www.dsfsolutions.com/"><u>Dynamic Site Framework</u></a>. Each organization has its unique set of requirements and IT governance that define its decision.&nbsp; But, under any circumstances, the task of migrating content into Publisher or out of Publisher doesn&#8217;t&nbsp;have to be a manual or laborious task.&nbsp; </p>
<p>Since the Portal&#8217;s inception during&nbsp;Plumtree days, a set of APIs were provided to programmatically interact with the underlying Portal objects.&nbsp; The API&#8217;s name might have changed through the product&#8217;s evolution &#8211; Enterprise Development Kit 5.x (EDK) during Plumtree days, Interaction Development Kit (IDK) 6.x during the portal&#8217;s short lived years with BEA and it seems that Oracle will retain the IDK name as it just prefixed it with &#8220;Oracle WebCenter&#8221; and just changed the version numbering to <a href="http://download.oracle.com/docs/cd/E13158_01/alui/idk/docs103/index.html"><u>10.x</u></a> Yet, the concept remains unchanged: a set of interfaces for Portal objects &#8211; portlets, documents, projects, folders, communities, security groups, etc.)</p>
<p>With that said, we compiled a high level example of how to programmatically import content items from an external CMS to UCM/Publisher. In a subsequent example we will address how to export content items from Publisher/UCM to HTML and then load these to a target CMS while leveraging its intrinsic API set.</p>
<p><span id="more-262"></span></p>
<p><font color="#00b050">//initially we want to establish a remote session to the portal where soapConnectionURL is web service end point<br /></font><font color="#0000ff">IRemoteSession remoteSession = RemoteSessionFactory.getExplicitLoginContext(<br />new URL(&#8220;http://YourPortalserver/ptapi/services/QueryInterfaceAPI&#8221;), yourUserName, yourPassword);</font><font color="#0000ff"><br />IContentFactory contentFactory = remoteSession.getContentFactory();</font></p>
<p><font color="#0000ff"></p>
<p></font><font color="#00b050">// get the required publisher object managers from IContentFactory<br /></font><font color="#0000ff">folderManager = contentFactory.getFolderManager();<br />contentItemManager = contentFactory.getContentItemManager();<br />propertyManager = contentFactory.getPropertyManager();<br />presentationTemplateManager = contentFactory.getPresentationTemplateManager();<br />dataEntryEntryTemplateManager = contentFactory.getDataEntryTemplateManager();<br /></font><font color="#00b050"></font></p>
<p><font color="#00b050">// create a text property to store HTML content<br /></font><font color="#0000ff">ITextBlockProperty textBlockProperty = propertyManager.createTextBlockProperty(&#8220;htmlTextProperty&#8221;, &#8220;htmlText&#8221;);<br />IFolder folder = folderManager.getFolderByPath(targetFolderPath&#8221;);<br /></font><font color="#00b050"></font></p>
<p><font color="#00b050">// create a presentation template that would use the html property<br /></font><font color="#0000ff">String templateText = &#8220;htmlTextProperty=&lt;pcs:value expr=\&#8221;htmlTextProperty\&#8221;&gt;unset&lt;/pcs:value&gt;\n&#8221;;<br />IPresentationTemplate presentationTemplate = presentationTemplateManager.createPresentationTemplate(folder, &#8220;Presentation Template&#8221;, templateText);<br />presentationTemplate.store();<br /></font><font color="#00b050"></font></p>
<p><font color="#00b050">// create a data entry template and attach the newly created presentation template<br /></font><font color="#0000ff">IDataEntryTemplate dataEntryTemplate = dataEntryTemplateManager.createDataEntryTemplate(folder, &#8220;Data Entry Template&#8221;);<br />dataEntryTemplate.addProperty(textBlockProperty);<br />dataEntryTemplate.attachPresentationTemplate(presentationTemplate);<br />dataEntryTemplate.store();<br /></font><font color="#00b050"></font></p>
<p><font color="#00b050">//create a content item and set the rich/block text property with the HTML from the source CMS<br /></font><font color="#0000ff">IContentItem contentItem = contentItemManager.createContentItem(folder, &#8220;contentItemNameGoesHere&#8221;, dataEntryTemplate);<br />textBlockProperty.setTextBlockProperty(&#8220;Hello &lt;strong&gt;&lt;font color=\&#8221;#000000\&#8221;&gt;World&lt;/font&gt;&lt;/strong&gt;&#8221;); <br />contentItemManager.checkInItem(contentItem, &#8220;Initial checkin.&#8221;);</p>
<p></font><font color="#00b050">// publish the content item<br /></font><font color="#0000ff">contentItemManager.publishContentItem(contentItem);</p>
<p></font>&nbsp;</p>
<p>The above code sample is a draft for how you can upload an HTML string from a separete CMS into Publisher as a content item, some of these method calls should be refactored outside the main method since, more likely, you&#8217;ll be looping through the source CMS content repository. Feel free to ping us if you have any questions.</p>
<p>&nbsp;</p>
<p>Thanks.<br /><font color="#0000ff"></font>&nbsp; </p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.function1.com/2009/04/import-content-into-publisher/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>The Exciting Conclusion of Stack Wars</title>
		<link>http://www.function1.com/2008/11/the-exciting-conclusion-of-stack-wars/</link>
		<comments>http://www.function1.com/2008/11/the-exciting-conclusion-of-stack-wars/#comments</comments>
		<pubDate>Sat, 22 Nov 2008 22:14:34 +0000</pubDate>
		<dc:creator>Brian Hak</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://wp.function1.com/index.php/254/uncategorized/the-exciting-conclusion-of-stack-wars</guid>
		<description><![CDATA[OK, now that you had your dinner and ate your meat, it&#8217;s time for the pudding.&#160; This conclusion to Stack Wars&#160;just ties up a few loose ends and walks through a &#8220;real-world&#8221; example of analyzing stack traces.&#160; Have fun&#8230;
Making Thread dumps easier to view
Seeing as how most people&#8217;s idea of a good time isn&#8217;t sifting [...]]]></description>
			<content:encoded><![CDATA[<p>OK, now that you had your dinner and ate your meat, it&#8217;s time for the pudding.&nbsp; This conclusion to Stack Wars&nbsp;just ties up a few loose ends and walks through a &#8220;real-world&#8221; example of analyzing stack traces.&nbsp; Have fun&#8230;</p>
<p><strong>Making Thread dumps easier to view</strong></p>
<p>Seeing as how most people&#8217;s idea of a good time isn&#8217;t sifting through pages upon pages of JVM stack traces, several good people have developed tools that make it easier to view and analyze complex thread dumps. Personally, I like and use the <a href="http://www.alphaworks.ibm.com/tech/jca" target="_new">IBM Alphaworks Thread and Monitor Dump Analyzer</a>. Pretty straight forward to use. Just save your thread dump off to a file and open it up in the Analyzer for a pretty view of all your threads that looks like this:</p>
<p>
<span class="mt-enclosure mt-enclosure-image" style="DISPLAY: inline"><img class="mt-image-none" height="635" alt="thread_analyzer.png" src="http://www.function1.com/site/2008/11/05/thread_analyzer.png" width="964" />&nbsp;</p>
<p>I&#8217;ve found this tool useful when I&#8217;m trying to look for patterns across many threads in a thread dump. Give it a try, you might like it.</p>
<p><span id="more-254"></span></p>
<p><strong>A real world example of how all the rambling I&#8217;ve just gone through came in handy</strong></p>
<p>Long ago, in a galaxy far, far away, I was working on a Plumtree consulting project with a large company. These folks had been having problems with their portal deployment. Periodically, the portal would start eating up 100% of the server CPU, and would never release it until the portal application server was bounced. During the time that the server CPU was pegged, users couldn&#8217;t access the portal&#8230;the customer was not happy. It was one of those big deals where VP-level people at the customer were yelling at VP/Executive level people at Plumtree on a daily basis. So here I am in this high stress situation. I arrive onsite with the customer and, for three days, nothing happens. The application doesn&#8217;t freak out, and all is fine. At this point, I&#8217;m starting to get cautiously optimistic that maybe we won&#8217;t see any problems during my remaining two days onsite, and somebody else will have to deal with the problem later :) But, alas, it wasn&#8217;t to be. About halfway through my second to last day with the customer everything went to hell. All of a sudden nobody could access the portal, so we start debugging. Sure enough, first thing we see is that the portal process is eating up 100% of the server CPU. These folks were running on a Unix platform, so I ask them to try:</p>
<p><em>kill -QUIT &lt;portal pid&gt;</em></p>
<p>After explaining for 20 minutes that, no, this command won&#8217;t kill the process, the server ops folks generated a thread dump and sent it over to review. After about 5 minutes of looking at the portal thread dump, it was pretty obvious that something was amiss with the portal code. The stack trace for EVERY SINGLE THREAD (All 100 or so of them) was exactly the same. They were all stuck running the same native method. Just to be sure this wasn&#8217;t some freak anomaly, we generated another thread dump 15 minutes later, and, yep, all the stack traces looked the same. So this tells us that there&#8217;s a problem with some native C code being used by the application&#8230;a good start. Unfortunately, since the problem was in native code, we couldn&#8217;t get a full stack trace from the JVM&#8230;it only goes so far as to let you know that it&#8217;s making a native call. So we dig one level deeper and trace the portal process. Running a trace/truss on a Unix process spits out all the system level calls that are being made. Wouldn&#8217;t you know it, when we looked at the trace output, 99% of the calls being made were:</p>
<p>poll(0)</p>
<p>Now, I wasn&#8217;t an expert at interpreting this level of data, but I knew enough that &#8220;poll&#8221; had something to do with sockets, and that there definitely shouldn&#8217;t be so many of those calls. Long story a little bit shorter, after a bunch of conference calls with Plumtree support and engineering, where we shared the data we&#8217;d gathered from the thread dumps and process traces, the engineering team found a very low level bug in the software and shipped a fix out to the customer&#8230;tragedy narrowly averted.</p>
</p>
<p><strong>Conclusion</strong></p>
<p>Did you really make it this far? If so, thanks for sticking with me, and I hope you found something of use in this long, winding post.&nbsp; If you&#8217;re ever stuck trying to make sense of a thread dump, feel free to drop us a line or post a comment here&#8230;we&#8217;ll do our best to help.</p>
<p>Take care, and remember, when dealing with production troubleshooting, &#8220;<a href="http://www.youtube.com/watch?v=8qur9LCjz84" target="_new">Do&#8230;or do not, there is no try</a>&#8220;. (This doesn&#8217;t have really have much to do with the post, but I&#8217;m kind of tired and pulling at straws for good ways to tie the Star Wars metaphor back in). Anyhow, as always, thanks for reading&#8230;see you next time.</p>
<p></span></i></p>
]]></content:encoded>
			<wfw:commentRss>http://www.function1.com/2008/11/the-exciting-conclusion-of-stack-wars/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stack Wars III (Or VII, depending on how you count): Return of the Stack</title>
		<link>http://www.function1.com/2008/11/stack-wars-iii-or-vii-depending-on-how-you-count-return-of-the-stack/</link>
		<comments>http://www.function1.com/2008/11/stack-wars-iii-or-vii-depending-on-how-you-count-return-of-the-stack/#comments</comments>
		<pubDate>Tue, 18 Nov 2008 23:11:01 +0000</pubDate>
		<dc:creator>Brian Hak</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://wp.function1.com/index.php/251/uncategorized/stack-wars-iii-or-vii-depending-on-how-you-count-return-of-the-stack</guid>
		<description><![CDATA[READER BEWARE: This got long and geeky, so make sure you&#8217;re really trying to avoid doing &#8220;real work&#8221; before you sit down to read.
Welcome back all, and thanks for joining me for the final installment of a three part series on decompiling Java code and analyzing stack traces. If you&#8217;re interested in the back story, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>READER BEWARE</strong>: This got long and geeky, so make sure you&#8217;re really trying to avoid doing &#8220;real work&#8221; before you sit down to read.</p>
<p>Welcome back all, and thanks for joining me for the final installment of a three part series on decompiling Java code and analyzing stack traces. If you&#8217;re interested in the back story, you can read about decompiling Java <a href="http://www.function1.com/site/2008/10/cool-tools-part-xxx-my-love-af.html">here</a>, and analyzing basic stack traces <a href="http://www.function1.com/site/2008/11/the-stack-trace-strikes-back.html">here</a>.</p>
<p>When we last left off, our hero was frozen in a block of Carbonite and left to his doom. Err&#8230;sorry, wrong story, let me start again.</p>
<p>When we last left off, we walked through analyzing a simple stack trace to run down a bug in a standalone Java program. This is all fine and good, but what happens when you&#8217;re running a Java application server (like Tomcat or Weblogic) that has hundreds of concurrent threads running tens of different web apps? And you&#8217;re just trying to figure out why your particular web application is hung? </p>
<p>Well, if you&#8217;re lucky, the developer of your web application was a good boy/girl, and they&#8217;re logging stack traces for you in a log file somewhere. If this is the case, then you can open up the log and analyze the trace like we did the <a href="http://www.function1.com/site/2008/11/the-stack-trace-strikes-back.html">last go round</a>. </p>
<p>Often times though, you&#8217;re not so lucky, and you have to dig a little deeper to figure out what&#8217;s going on. Say, for instance, your web application just starts responding very slowly. You see from access logs that responses are being served back to users, but they&#8217;re about 5 times slower than normal&#8230;WTF? Or, what if your application server starts pegging the box at 100% CPU&#8230;what to do? Or, out of nowhere, your app server starts throwing Java.lang.OutOfMemory exceptions&#8230;Gah!!! Sadly, these nebulous problems seem to happen in a production environment more often than most of us would like to admit. And when they do occur, it&#8217;s usually a high stress situation because there&#8217;s probably a production outage and nobody really knows why. So, how do we find a better fix to the problem than the traditional, &#8220;Let&#8217;s just bounce it and see what happens&#8221; response? Why, we use &#8220;The Force&#8221;, of course. Except in this case, &#8220;The Force&#8221;, is just a set of debugging tips that I&#8217;m getting ready to share with you as follows:</p>
<ol>
<li>Take a deep breath and don&#8217;t freak out when a bunch of people start yelling.</li>
<li>Understand the severity of the situation. Figure out how much downtime you can tolerate for debugging before things really hit the fan.</li>
<li>Set expectations. Let people know when they can expect the issue to be fixed. If you know a bounce will temporarily fix the problem, then set a drop-dead time for debugging and schedule a bounce. Let folks know that if you don&#8217;t find a root-cause of the problem, that they should expect to see the issue again.</li>
<li>Gather as much information about the problem as you can. What, specifically, are users experiencing? Can you reproduce? What are the symptoms? What log messages do you have? What does the server environment look like? etc.</li>
<li>Try to relate this issue to something you&#8217;ve seen in the past. Does this look like a problem you saw last week or last month? What did you do to fix it then? Why is it popping up again now?</li>
<li>Eliminate possible external causes. Is this actually a network problem in disguise? Is the database acting up? Is some other process on the server eating up CPU? Is the server constantly swapping because it doesn&#8217;t have enough RAM to handle all its business?</li>
<li>Eliminate environment changes as possible causes. Has the server environment changed recently? Could this be causing your problem? </li>
<li>Look in earnest at your application server process. Are we bumping up against the Java max. heap size? Are we seeing lots of garbage collection? Is our thread pool exhausted? Is our JDBC pool maxed out?</li>
<li>Take a look inside of the application server JVM. Generate a thread dump to get a snapshot of how your application server is behaving. Analyze the stack traces in the thread dump, and look for points of interest, like&#8230;race conditions, stuck threads, deadlock, etc.</li>
<li>Open a ticket with the software vendor (If applicable)</li>
<li>Pray the issue fixes itself and doesn&#8217;t come back</li>
<li>Find a new job so you don&#8217;t have to deal with these problems anymore</li>
</ol>
<p>Read on for more fascinating details about The Stack Trace&#8230;</p>
<p><span id="more-251"></span></p>
<p>At the risk of getting back on topic, the rest of this post will focus on point 9: <strong>Take a look inside of the application server JVM</strong>. Did you know that you can generate a snapshot of all the JVM&#8217;s threads? Doing so, in practice, creates a big stack trace that tells you what your application server is doing at a point in time. For instance, here&#8217;s part of a thread dump/stack trace from a Weblogic Server running on my laptop:</p>
<p>&nbsp;</p>
<p><img class="mt-image-none" style="WIDTH: 545px; HEIGHT: 578px" height="858" alt="wl_thread_dump.png" src="http://www.function1.com/site/2008/11/05/wl_thread_dump.png" width="677" />&nbsp;</p>
<p>&nbsp;</p>
<p>Looks a lot more complicated than that simple stack trace we looked at last time, huh?</p>
<p><img class="mt-image-none" height="340" alt="stack_trace_read_info.png" src="http://www.function1.com/site/2008/10/17/stack_trace_read_info.png" width="677" />&nbsp;</p>
<p>&nbsp;</p>
<p>Before we start trying to make sense out of all this information, let&#8217;s first step back and talk about how we generate a thread dump in the first place. Basically you have a few options. If you&#8217;re running on a Unix platform, you can send SIGQUIT to the JVM and it will push a thread dump to the standard error stream. You send SIGQUIT to the process as follows:</p>
<p><em>kill -QUIT &lt;pid&gt;</em></p>
<p>or</p>
<p><em>kill -3 &lt;pid&gt;</em></p>
<p>The above commands are identical, and don&#8217;t worry&#8230;even though we&#8217;re using the &#8220;kill&#8221; command, they won&#8217;t actually shutdown/kill your process.</p>
<p>What&#8217;s that you say? You&#8217;re running your app server on Windows and this Unix example is totally useless? Let me digress for a minute and say&#8230;if you&#8217;re going to be running on Windows, you might as well be running IIS/.NET, it&#8217;s just a better fit. But I assume it will take you a while to change your OS and/or development platform, so while we&#8217;re waiting, here&#8217;s how you can generate a thread dump for your app server on Windows.</p>
<p>1) Start your Application Server from a DOS prompt</p>
<p>2) Type <em>&lt;Ctrl&gt;&lt;Break&gt;</em> in DOS window running your application to send a thread dump to the DOS terminal</p>
<p>Additionally, if you happen to be running Weblogic 9+, you can generate a stack trace through the Admin console by going to Servers-&gt;&lt;Your Server&gt;-&gt;Monitoring-&gt;Threads-&gt;Dump Thread Stats</p>
<p><img class="mt-image-none" height="870" alt="wl_admin_console.png" src="http://www.function1.com/site/2008/11/05/wl_admin_console.png" width="1440" />&nbsp;</p>
</p>
<p>Great, so now we have about 2500 lines of output&#8230;how do we do something useful with all this data? Let&#8217;s start by discussing what we&#8217;re looking at from a high-level. As I mentioned earlier, our thread dump is a snapshot of the state of the JVM at a point in time. Since we know our application server is a multi-threaded application, and that each thread has its own call stack, the thread dump is actually just &#8220;n&#8221; stack traces, where &#8220;n&#8221; is equal to the number of threads running inside of your application server. So let&#8217;s first look at each stack in isolation. For instance, you might have one thread that looks like:</p>
<p>
<p><img class="mt-image-none" height="490" alt="waiting_thread_overview.png" src="http://www.function1.com/site/2008/11/05/waiting_thread_overview.png" width="677" /></p>
<p>The first line just gives us some information about the thread itself. We see that this thread looks like it&#8217;s an execution thread that services user requests. Furthermore, it&#8217;s the sixth member of a thread pool that&#8217;s used to handle all incoming requests. </p>
</p>
<p><img class="mt-image-none" height="490" alt="waiting_thread_first_line.png" src="http://www.function1.com/site/2008/11/05/waiting_thread_first_line.png" width="677" />&nbsp;</p>
<p>&nbsp;</p>
<p>Now, following the same principles discussed in <a href="http://www.function1.com/site/2008/11/the-stack-trace-strikes-back.html">my last post</a>, let&#8217;s look at the trace from the bottom up:</p>
<p><img class="mt-image-none" height="490" alt="waiting_thread_stack.png" src="http://www.function1.com/site/2008/11/05/waiting_thread_stack.png" width="677" />&nbsp;</p>
<p>Reading bottom to top, we see that the thread was spawned by the application server code, and not through a main method, and that it&#8217;s sitting in Object Wait state. We can interpret this to mean that the thread is sitting idle, just waiting to service requests. In short, not much of interest is going on here. So let&#8217;s look at another example like this:</p>
<p><img class="mt-image-none" height="490" alt="gc_thread.png" src="http://www.function1.com/site/2008/11/05/gc_thread.png" width="677" />&nbsp;</p>
<p>By the name, we can assume that this thread is being used internally by the application server to monitor garbage collection. Once you start looking at a few application server thread dumps, you&#8217;ll notice that there are a bunch of threads like this one. That is, the app server spawns a bunch of threads to do internal housekeeping. Do yourself a favor, just ignore these stacks. For our purposes, they&#8217;re just noise. So either skim over them, or delete them altogether from your thread dump, they&#8217;re only taking up space and causing confusion.</p>
<p>OK, so we&#8217;ve looked over all the individual stack traces that are actually serving user requests and don&#8217;t have anything that&#8217;s particularly compelling&#8230;now what? Now we look for trends. Did you happen to notice that the stack traces for all your threads look the same? Maybe they&#8217;re all waiting for a JDBC call to be returned&#8230;this implies that perhaps we have a problem at the database level. Let&#8217;s go look at that database again. Are all the threads in your execution pool busy without any waiting to service requests? If so, maybe you&#8217;re over-loading your application server and need to add more threads to the execution pool. Still nothing interesting? All the threads look like they&#8217;re behaving normally? Well, let&#8217;s complicate things a bit more by taking another thread dump. By taking a second (or third or fourth) thread dump, we now have a chronology of how the JVM is behaving at distinct points in time. So compare and contrast what specific threads are doing across each of your thread dumps. If, for instance, you see that all the threads show the same stack trace in all of your thread dumps, you can logically conclude that the JVM/application server isn&#8217;t servicing requests the way it should be, and you have &#8220;stuck threads&#8221;. So what&#8217;s causing these stuck threads? Two likely candidates:</p>
<ol>
<li>Something external to the JVM is acting up. Is some other process on the server eating up all the CPU and starving your application server process? Is the server out of RAM?</li>
<li>Your web application is dead-locked, or in a race condition. This is the result of poor programming in multi-threaded applications, and is often very difficult to run down. Basically, thread A is holding a resource that thread B is waiting for, and thread B is holding a resource that thread A is waiting for. The two threads will never move forward in their execution because they&#8217;re in a stalemate over who will give up their resources first. This is probably the worst explanation ever of dead-lock, so if you&#8217;re interested in more details, Google &#8220;<a href="http://en.wikipedia.org/wiki/Dining_philosophers_problem" target="_new">Dining Philosphers</a>&#8220;.</li>
</ol>
<p>For the sake of argument, let&#8217;s assume that there&#8217;s nothing wrong with the server that&#8217;s running your process, so you think you might have a deadlock. How can you be sure? Conveniently, stack traces in JDK 1.5+ actually give you a little deadlock summary at the bottom like so:</p>
<p>
<p><img class="mt-image-none" height="490" alt="jvm_deadlock.png" src="http://www.function1.com/site/2008/11/05/jvm_deadlock.png" width="677" /></p>
<p>If you see a deadlock message in the stack trace, you can be about 100% sure there&#8217;s something funky going on with the code. At this point, you need to either dive deep into the code and figure out where the threading logic is flawed, or send all the information you&#8217;ve collected over to someone who can. </p>
<p>I know I told you this was the final installment at the start of this post&#8230;but it got longer than expected.&nbsp; So&#8230;join us next week for&nbsp; some cool stack trace tools and&nbsp;a real world example.&nbsp; Until then&#8230;.may the force be with you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.function1.com/2008/11/stack-wars-iii-or-vii-depending-on-how-you-count-return-of-the-stack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AJAX Refresher</title>
		<link>http://www.function1.com/2008/11/ajax-refresher/</link>
		<comments>http://www.function1.com/2008/11/ajax-refresher/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 03:23:00 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://wp.function1.com/index.php/252/uncategorized/ajax-refresher</guid>
		<description><![CDATA[It&#8217;s been a while since we touched on AJAX, but a question came up recently about it an I thought it might be good to review. AJAX, or &#8220;Asynchronous JavaScript and XML&#8221;, is a way for portlet developers to create rich Web Applications that don&#8217;t require the entire browser page to refresh to update content.&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s <a href="http://www.function1.com/site/2007/05/handling-ajax-timeouts.html">been a while</a> since we touched on <a href="http://en.wikipedia.org/wiki/AJAX" target="_new">AJAX</a>, but a question came up recently about it an I thought it might be good to review. AJAX, or &#8220;Asynchronous JavaScript and XML&#8221;, is a way for portlet developers to create rich Web Applications that don&#8217;t require the entire browser page to refresh to update content.&nbsp; This is done by making asynchronous calls to the server and updating content within the page itself.&nbsp; With the AquaLogic portal, this means that portlets can dynamically update content in &lt;div&gt; tags by requesting new content without having to refresh the entire page (and other portlets on the page).&nbsp; It&#8217;s a pretty simple concept; in many cases you can accomplish this without having to even change any code &#8211; you can just specify &#8220;inline refresh&#8221; on the Web Service and the portal will automatically rewrite the HTML links on the page to make AJAX calls:</p>
<p><img class="mt-image-none" height="246" alt="inline_refresh.jpg" src="http://www.function1.com/site/2008/11/10/inline_refresh.jpg" width="404" /></p>
<p>The HTML rewrites cause the browser to make the HTTP request &#8220;behind the scenes&#8221;, and when a response comes back, the portal refreshes the content inside the portlet &lt;div&gt; tag.</p>
<p><span id="more-252"></span></p>
<p>But there are some things to know about this AJAX stuff, so here are a couple of refresher points about AJAX:</p>
</p>
<p>1) The response to an AJAX request is basically just a text string to a browser, and it&#8217;s up to your JavaScript to interpret it.&nbsp; Often you do something like:</p>
<p>
<pre>document.getElementById("responseDivTag").innerHTML = response.getResponse();</pre>
<p>&#8230; to refresh content.&nbsp; But note that this doesn&#8217;t tell the browser to &#8220;process&#8221; the response &#8211; specifically, JavaScript that comes back in the response won&#8217;t run, because all we&#8217;re doing is setting the HTML to a string that comes back from the server.&nbsp; In order to run JavaScript in the response, you should look into the <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/eval" target="_new">JavaScript &#8220;eval()&#8221; method</a>, which will take a string returned from the server and run it as JavaScript.&nbsp; Just make sure you don&#8217;t include the &lt;script&gt; tags in your response if you really are returning JavaScript and are parsing it as such.</p>
<p>2) The response does not have to actually be HTML!&nbsp; It&#8217;s just a string to the browser, and you can do anything with it.&nbsp; The most common use (which <a href="http://www.function1.com/site/products/">all of our products</a> use) is to return <a href="http://en.wikipedia.org/wiki/JSON">JSON</a>, or &#8220;JavaScript Object Notation&#8221;, which can then be treated as objects that your script can handle however you want.&nbsp; Let&#8217;s say you just want to know if there was a success or failure: you could literally just return a &#8220;0&#8243; or &#8220;1&#8243; in your response and write something like:</p>
<p>
<pre>if (response.getResponseText.equals("1"))


&nbsp;&nbsp; alert("success!");

else

&nbsp;&nbsp;&nbsp;alert("fail");
</pre>
<p>Obviously, this just barely scratches the surface on AJAX, and you can rest assured that you haven&#8217;t heard the last of it.&nbsp; AJAX is the cornerstone of pretty much all future Oracle portal technologies, and if you&#8217;re a web developer who&#8217;s not all that familiar with it, trust me:&nbsp; you will be soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.function1.com/2008/11/ajax-refresher/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Stack Trace Strikes Back</title>
		<link>http://www.function1.com/2008/11/the-stack-trace-strikes-back/</link>
		<comments>http://www.function1.com/2008/11/the-stack-trace-strikes-back/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 03:56:00 +0000</pubDate>
		<dc:creator>Brian Hak</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Logging]]></category>

		<guid isPermaLink="false">http://wp.function1.com/index.php/250/uncategorized/the-stack-trace-strikes-back</guid>
		<description><![CDATA[Howdy all. Welcome to part two of three of what was originally conceived as a one part series. It&#8217;s entirely possible that I&#8217;ll get all George Lucas on you years from now and produce some more of these posts that are a complete letdown and affront to your childhood memories, but I digress. For now, [...]]]></description>
			<content:encoded><![CDATA[<p>Howdy all. Welcome to part two of three of what was originally conceived as a one part series. It&#8217;s entirely possible that I&#8217;ll get all George Lucas on you years from now and produce some more of these posts that are a complete letdown and affront to your childhood memories, but I digress. For now, rest assured that this post will knock your socks off as a follow-up to my last <a href="http://www.function1.com/site/2008/10/cool-tools-part-xxx-my-love-af.html">tidbit</a> on decompiling Java code.</p>
<p>Without further ado, I give you&#8230;Stack Wars II: The Stacktrace Strikes Back (I&#8217;m completely aware that I&#8217;m abusing the metaphor here, but isn&#8217;t that really what blogging is all about?).</p>
<p>Standard disclaimer: This post is intended for a technical audience with a focus on production support. Also, everything here is Java focused, but you can certainly apply some of the concepts in a .NET environment as well&#8230;you&#8217;ll just have to create your own screencaps to replace the examples I&#8217;ve included below.</p>
<p>So, what is a stack trace, and why should you care? Well, one question at a time please.</p>
<p><strong>What is a stack trace?</strong> </p>
<p>Wikipedia says a Stack Trace is, &#8220;A report of the active stack frames instantiated by the execution of a program.&#8221; Now, I vaguely understand the Wikipedia definition, but I have also have a computer science degree from a second tier state university, so let me try to translate for those of you who were smart enough to get degrees in something besides CompSci: a Stacktrace is a snapshot of a program&#8217;s behavior at a point in time. In the Java world, a stack trace will tell you which method was being executed at the time the trace was generated, along with its complete call stack, and usually line numbers as well. Take a look at the following simple stack trace below as an example:</p>
<p><img class="mt-image-none" height="340" alt="stack_trace.png" src="http://www.function1.com/site/2008/10/13/stack_trace.png" width="677" /> </p>
<p><strong>Why should you care?</strong></p>
<p>Good question. I&#8217;d venture a guess and say that about 99.99% of the world doesn&#8217;t need to know nor care about stack traces. But here you are reading this post none-the-less, so here&#8217;s why they&#8217;re important:</p>
<p>1) Good programmers almost always print stack traces out in log files when an error in a program occurs. This gives us a useful tool&nbsp;to track down bugs. Whether you&#8217;re just reporting information to a support team somewhere, or getting a little sassy and trying to fix a problem yourself, the stack trace is like a map for finding treasure buried deep in code. Except that instead of finding actual treasure, you&#8217;re just finding a logic error. And instead of getting rich, you just get to complain about&nbsp;a problem, and maybe fix it.</p>
<p>2) You can tell the JVM to generate a stack trace for a running process. Doing so allows us to take a snapshot of the JVM at an arbitrary point in time, and see what all its threads are up to. This is useful when trying to figure out why a process (Tomcat for instance) is zombied (i.e. it&#8217;s running, but not responding to requests), or when you&#8217;re trying to fix deadlock issues, which are particularly difficult to run down.</p>
<p>Hit the jump for learning more about reading and interpreting stack traces!</p>
<p><span id="more-250"></span></p>
<p><strong>Reading Stack Traces</strong></p>
<p>Stack Traces range from very easy to very difficult to read, depending on what you&#8217;re looking at. For instance, a stack trace of a single-threaded, stand-alone Java program is almost trivial to interpret, whereas trying to find dead-locks in a Java application server that has 100+ concurrent threads can be pretty cumbersome. Let&#8217;s use our last example again to walk through interpreting a &#8220;simple&#8221; stack trace:</p>
<p><img class="mt-image-none" height="340" alt="stack_trace.png" src="http://www.function1.com/site/2008/10/13/stack_trace.png" width="677" /> </p>
<p> When reading traces, I recommend first taking a look at the top line of the stack trace to see what error is occurring. In this case, it looks like we&#8217;re getting a NullPointerException in the &#8220;doEvenMoreStuff&#8221; method on line 22 of Broken.java:   </p>
<p><img class="mt-image-none" height="340" alt="stack_trace_1st_line.png" src="http://www.function1.com/site/2008/10/17/stack_trace_1st_line.png" width="677" />  </p>
<p> After getting a rough idea of the error being thrown, it&#8217;s worthwhile to read the stack from the bottom up; least specific to most specific. In our example, for instance, we see from the last line of the trace that the first call in the stack originated in the main method of Broken.java. Since we all know that &#8220;main&#8221; is the first thing invoked when running a program from the command-line, we can feel confident that stepping through Broken.java beginning on line 36 in the main method will help us fully understand what&#8217;s gone wrong in the code. So we look at the next line up in the trace, where we see a call from main to the method, &#8220;doStuff&#8221;. &#8220;doStuff&#8221; calls &#8220;doMoreStuff&#8221; on line 16 of Broken.java, which in turn calls the &#8220;doEvenMoreStuff&#8221; method. Finally we get back to the NullPointerException, which occurs on line 22:   </p>
<p><img class="mt-image-none" height="340" alt="stack_trace_read_info.png" src="http://www.function1.com/site/2008/10/17/stack_trace_read_info.png" width="677" /> </p>
<p> At this point, you have a few options to continue your troubleshooting.</p>
<p> 1) Assuming you&#8217;re trying to fix a problem with some commercially supported software, you can open a trouble ticket with the vendor. Provide symptoms that you&#8217;ve noticed and the stack trace you&#8217;ve captured. The support team can then pass off the trace to an engineer for a looksy, and maybe you end up with a patch somewhere down the road.</p>
<p> 2) Google the hell out of the exception. The internet is a strange and beautiful place, and you&#8217;d be amazed how many times you can find answers out there. For instance, let&#8217;s say that instead of seeing, &#8220;NullPointerException&#8221; in the first line of your stack trace, you instead see something like, &#8220;AnalyticsConfigurationException&#8221;. You start Googling around for things like, &#8220;ALUI AnalyticsConfigurationException&#8221;, &#8220;AnalyticsConfigurationException&#8221;, etc. and see what you see. Maybe you find nothing, but maybe you find some blog post that tells you this error means that you have a typo in line 18 of some configuration file. </p>
<p>Just to repeat&#8230;Google the hell out of the exception. Low cost, high potential reward in doing so. You know those smart tech guys who sit in the corner and don&#8217;t really get enough sun&#8230;I guarantee you that one of their best tricks is knowing how to use the internet to find information. </p>
<p> 3) You want to be a maverick like John McCain, and decide to decompile the code to fix the problem yourself. Well God bless you, and God bless the <st1:country-region w:st="on"><st1:place w:st="on">United States of America</st1:place></st1:country-region>&#8230;take a look <a href="http://www.function1.com/site/2008/10/cool-tools-part-xxx-my-love-af.html">here</a> for more details.</p>
<p> 4) You happen to have the source code for this application available, and decide to match up the stack trace to the code. This is pretty easy to do when you have the original source, as the line numbers in your stack trace will match up to the code you have. So just read the line numbers in the stack from bottom up, and step through the code accordingly; like this:   </p>
<p><img class="mt-image-none" height="490" alt="stacktrace_with_code_main.png" src="http://www.function1.com/site/stacktrace_with_code_main.png" width="677" /></p>
<p><img class="mt-image-none" height="666" alt="dostuff.png" src="http://www.function1.com/site/dostuff.png" width="677" /></p>
<p><img class="mt-image-none" height="698" alt="doMoreStuff.png" src="http://www.function1.com/site/doMoreStuff.png" width="677" /></p>
<p><img class="mt-image-none" height="698" alt="even_more_stuff.png" src="http://www.function1.com/site/even_more_stuff.png" width="677" /></p>
<p>That&#8217;s it for now. I hope this rambling has helped you get a handle on why stack traces are useful, and how to start making sense of them. Be sure to stay tuned for next week&#8217;s installment, &#8220;Return of the Stack Trace&#8221;, where we walk through interpreting some more involved traces&#8230;Same bat time, same bat channel. Until then, may the force be with you (Mixing metaphors is also totally acceptable in the wonderful world of blogging).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.function1.com/2008/11/the-stack-trace-strikes-back/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cool Tools Part XII: ALUI JavaScript Debugger</title>
		<link>http://www.function1.com/2008/06/cool-tools-part-xii-alui-javascript-debugger/</link>
		<comments>http://www.function1.com/2008/06/cool-tools-part-xii-alui-javascript-debugger/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 08:11:00 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Portal Server]]></category>

		<guid isPermaLink="false">http://wp.function1.com/index.php/218/uncategorized/cool-tools-part-xii-alui-javascript-debugger</guid>
		<description><![CDATA[Yeah, this one is only marginally useful, can only be considered a &#8220;Cool Tool&#8221; in the broadest sense of the title, and not nearly as fun of an Easter Egg as&#160;we&#8217;ve posted in the past, but it&#8217;s neat to check out JavaScript internals of the portal nonetheless.
Basically, open up your portal in FireFox (this doesn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>Yeah, this one is only marginally useful, can only be considered a &#8220;Cool Tool&#8221; in the broadest sense of the title, and not nearly as fun of an Easter Egg as&nbsp;<a href="http://www.function1.com/site/2007/03/tetris-anyone.html">we&#8217;ve posted in the past</a>, but it&#8217;s neat to check out JavaScript internals of the portal nonetheless.</p>
<p>Basically, open up your portal in FireFox (this doesn&#8217;t seem to work in IE), and hit CTRL-SHIFT-3.&nbsp; That is, hold down CTRL and SHIFT and hit 1, 2, or 3.&nbsp; You&#8217;ll get a little JS window at the bottom of your portal page showing some JS debug information that you can use to see what&#8217;s going on under the covers and evaluate ALI portal JS objects in real time.</p>
<p>The &#8220;1, 2, or 3&#8243; that I mentioned above refers to the log threshold you&#8217;d like to look at (use &#8220;0&#8243; to turn it off); three is the highest.</p>
<p><span id="more-218"></span></p>
<p>Fun?&nbsp; If you&#8217;re a curious techie who gets a thrill out of this sort of stuff.&nbsp; Useful?&nbsp; I&#8217;ve never used it (but then again,&nbsp;I only meet the first two of these criteria.&nbsp; OK, fine, who am I kidding, I meet all three &#8211; but it&#8217;s still&nbsp;never been&nbsp;useful for me).</p>
<p><p><img class="mt-image-none" height="289" alt="js_debug.jpg" src="http://www.function1.com/site/2008/06/02/js_debug.jpg" width="791" /></p>
<p>Find any practical uses for this hidden feature?&nbsp; Hit me up in the comments.</p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.function1.com/2008/06/cool-tools-part-xii-alui-javascript-debugger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
