<?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>java rants &#187; Sam Pullara</title> <atom:link href="http://www.javarants.com/author/sam/feed/" rel="self" type="application/rss+xml" /><link>http://www.javarants.com</link> <description>Rants about Java and other internet technologies by Sam Pullara</description> <lastBuildDate>Sun, 09 Oct 2011 23:29:31 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.2.1</generator> <item><title>New features and extensions in Mustache.java</title><link>http://www.javarants.com/2011/10/09/new-features-and-extensions-in-mustache-java/</link> <comments>http://www.javarants.com/2011/10/09/new-features-and-extensions-in-mustache-java/#comments</comments> <pubDate>Sun, 09 Oct 2011 23:29:31 +0000</pubDate> <dc:creator>Sam Pullara</dc:creator> <category><![CDATA[Technology]]></category> <guid
isPermaLink="false">http://www.javarants.com/?p=1440</guid> <description><![CDATA[Almost a year and a half ago I talked about my implementation of mustache, which I call mustache.java. Since then, we used it to develop Bagcheck and it has also been adopted for a variety of use cases by Netflix, Twitter &#8230; <a
href="http://www.javarants.com/2011/10/09/new-features-and-extensions-in-mustache-java/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Almost a year and a half ago <a
href="http://www.javarants.com/2010/06/16/building-the-ideal-web-application-template-engine/" target="_blank">I talked about</a> my implementation of <a
href="http://mustache.github.com/" target="_blank">mustache</a>, which I call <a
href="https://github.com/spullara/mustache.java" target="_blank">mustache.java</a>. Since then, we used it to develop <a
href="http://bagcheck.com" target="_blank">Bagcheck</a> and it has also been adopted for a variety of use cases by <a
href="http://netflix.com" target="_blank">Netflix</a>, <a
href="http://twitter.com" target="_blank">Twitter</a> and others. In my post I mention that for all intents and purposes, the template engine was &#8216;finished&#8217; and I would say that for the most part, that was accurate. However, there have been a couple of things that have been done since then around optimization and also some interesting extensions that I would like to share with people to get feedback.<span
id="more-1440"></span></p><p>First though, I will shortly recap the biggest differentiating feature of this implementation over other implementations:</p><ul><li>Concurrent, streaming template evaluation</li></ul><p>Mustache.java exectutes the template in such a way that partials, loops and even replacement (if you use futures) do not block the further evaluation of the template. This allows you to quickly launch all your I/O (or CPU) bound work for the whole template in context during a quick evaluation and then the engine can do things like flush to the underlying writer incrementally as work completes giving you great client-side and server-side concurrency. You can also use this to defer sections of the page to write them out later, a la <a
href="https://www.facebook.com/note.php?note_id=389414033919" target="_blank">Big Pipe</a>. This has been invaluable to easily maintaining Bagcheck&#8217;s low-latency design. The downside to this is that you need to write your Java code in a functional style, I suggest that you use <a
href="http://code.google.com/p/guava-libraries/" target="_blank">Google collections</a> to do it right. The design of this has remained unchanged since the initial release though recently I added the ability for the template backing code writer to take control of concurrency in order to reduce context switches and garbage creation. This can get you a 5x improvement in template evaluation performance at the cost of developer time and expertise without losing the ability to do concurrent evaluation when necessary.</p><p>Since the first release, the <em>handlebar server</em> has been included to allow you to easily view mustache templates fully rendered in the browser with only JSON data as your backing code. This lets you quickly iterate on design without having to have the full stack running with enough information for someone to figure what needs to be implemented on the backend when new things are added. Sometimes though it can be painful to get realistic data for new features using production data. In those cases, I had always imagined a method to take a template and rendered content and give you back data would generate that same content in combination with the template. That functionality is now in the master branch (since 0.6-SNAPSHOT). Given any Mustache instance you can now call <em>unexecute(content)</em> on that instance and if it isn&#8217;t ambiguous or in some other way irreversible you will get back a Scope object that contains the data. Using <em>toJSON()</em> on that object will provide mock data that can be used with <em>handlebar</em>. Here is an example:</p> <script src="http://gist.github.com/1274327.js"></script><br
/> <script src="http://gist.github.com/1274330.js"></script> <p>We then take the template and the output and unexecute them using the new method on Mustache objects:</p> <script src="http://gist.github.com/1274334.js"></script> <p>This produces the following JSON (after pretty printing):</p> <script src="http://gist.github.com/1274337.js"></script> <p>What it really does is turn the Mustache language into a look ahead grammar that can be used to read data from content, though that content has to be stringently authored. Another use case that seems reasonable to me is for people to check that their complicated backend code is combining in the right way with their template. Something like an integration test for template processing without having to hard code the non-template interpolated text into your test. Would love to get feedback on this feature as it is still unclear whether it will be useful to a wide audience.</p><p>The most recent feature added is support for Twitter-style functions (_ vs just #) and i18n support. Long ago I had added support for # functions: you can return a Google Guava Function from the value callback and after the engine executes the enclosed template it will call your function to transform the value. This works for simple i18n and caching but fails for more complicated i18n applications. In those cases, you may want to also change the template itself which means you will need a callback before the underlying template is executed. If you need that behavior, you instead return an instance of TemplateFunction which gets called back before evaluation and then compiles the template text that you return from the function invocation. This is most often used to change the order of words or phrases that include things like user names. Here is a simple example from the tests:</p> <script src="http://gist.github.com/1274365.js"></script> <p>The biggest change since the release though is the addition of the <em>MustacheBuilder</em>. In 0.6 I will be deprecating <em>MustacheCompiler</em> as not only does the <em>Builder</em> not require the use of the Java compiler, but it also compiles almost instantly and performs better than the Java compiled versions of the templates. The <em>Builder</em> also gives us a lot more runtime flexibility that I am going to take advantage of over time for a variety of optimizations that are in the queue. I may return to investigate using <em>ASM</em> for compilation though in order to take advantage of JDK 7 and <em>invokedynamic</em> as that becomes the standard JVM in deployment.</p><p>You may not be familiar with some of the things that you can enabled while it is running to make debugging and profiling easier. There are 3 system properties that can be turned on with little documentation:</p><ul><li>mustache.debug: output a warning when a callback is absent or null</li><li>mustache.trace: create a multithreaded trace, use MustacheTrace.setUniqueId() in each thread, output with MustacheTrace.toASCII()</li><li>mustache.profile: time all callbacks, output the top 10 total + average with Scope.report() and then reset the profiler</li></ul><p>Now is the time for input. Here are some things that I have on my TODO list:</p><ul><li>Full JDK7 invokedynamic support with ASM generated classes</li><li>Extensible templates a la Django templates</li><li>Native Scala support based on Twitter&#8217;s util-core</li><li>Generate scaffolding in a variety of languages for backing code with verification</li></ul><div><span
style="font-size: small;"><span
class="Apple-style-span" style="line-height: 24px;">Would love to hear from users and prospects. You can either comment here or join the dicsussions on the <a
href="http://groups.google.com/group/mustachejava">Mustache.java group</a>.</span></span></div> ]]></content:encoded> <wfw:commentRss>http://www.javarants.com/2011/10/09/new-features-and-extensions-in-mustache-java/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Using Closures, Method Handles and Extension Methods in Java 8 (JSR-335)</title><link>http://www.javarants.com/2011/01/22/using-closures-method-handles-and-extension-methods-in-java-8-jsr-335/</link> <comments>http://www.javarants.com/2011/01/22/using-closures-method-handles-and-extension-methods-in-java-8-jsr-335/#comments</comments> <pubDate>Sun, 23 Jan 2011 01:57:53 +0000</pubDate> <dc:creator>Sam Pullara</dc:creator> <category><![CDATA[Technology]]></category> <guid
isPermaLink="false">http://www.javarants.com/?p=1389</guid> <description><![CDATA[Update: A bunch of code from hotspot was just integrated into the bsd-port and some of it breaks the build. Use my distribution at the end of this blog post if you want to test the features. In December JSR-335 &#8230; <a
href="http://www.javarants.com/2011/01/22/using-closures-method-handles-and-extension-methods-in-java-8-jsr-335/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p><b>Update:</b> A bunch of code from hotspot was just integrated into the bsd-port and some of it breaks the build. Use my distribution at the end of this blog post if you want to test the features.</p><p>In December JSR-335 was approved by the JCP and is now starting. I&#8217;ve joined as member of the expert group, but like with most recent JSRs all the real discussion will take place on the public mailing list. A lot of work has already been done in OpenJDK to support the features of this JSR which will ultimately be included in Java 8 if it completes successfully. Here is the <a
href="http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3.html">current state of the JSR</a>. Though JDK 8 is when official support would ship, you can already build and execute the draft features of JSR-335 by using the regular OpenJDK 7 build along with some compile-time and run-time tools. Before I go into the guts of how to build them, here are some examples of what you will be able to do:<br
/> <span
id="more-1389"></span></p><ul><li>Create closures that are converted to Single Abstract Method (SAM) implementations when used in context</li><li>Create interfaces that specify default behavior for methods that are unimplemented by the implementing class</li><li>Reference methods in source and then convert those references to SAM implementations when used in context</li></ul><p>Building OpenJDK 7 on Mac OS X 10.6 (based on <a
href="http://wikis.sun.com/display/OpenJDK/Darwin10Build">Darwin10Build</a>):</p><ul><li>Install mecurial:<br
/> <code>sudo port install mercurial</code></li><li>Install hg-forest:<br
/> <code>sudo port install hg-forest</code></li><li>Install <a
href="http://hg.bikemonkey.org/archive/javasrc_1_6_jrl_darwin/soylatte16-i386-1.0.3.tar.bz2">soylatte</a> to /usr/local/soylatte16-i386-1.0.3</li><li>Clone bsd-port:<br
/> <code>hg fclone http://hg.openjdk.java.net/bsd-port/bsd-port</code></li><li><code>export OPENJDK_ROOT=`pwd`</code></li><li>Grab build script:<br
/> <code>cd bsd-port; curl -O "https://gist.github.com/raw/617451/d4862a41b07a1196d5149efc1c40406f8bb77dc1/update.sh"</code></li><li><code>mkdir ALT_COMPILER_PATH;cd ALT_COMPILER_PATH;<br
/> ln -s /usr/bin .SOURCE;ln -s .SOURCE/g++-4.0 g++;<br
/> ln -s .SOURCE/gcc-4.0 gcc;cd ..</code></li><li><code>unset JAVA_HOME</code></li><li>Edit hotspot/make/bsd/makefiles/defs.make and change ifeq ($(ARCH), amd64) to ifeq($(ARCH), x86_64)</li><li>Update sources and build (on a fast machine will take 15m):<br
/> <code>sh update.sh</code></li></ul><p>Now you should have a fully working OpenJDK 7 64-bit distribution:<br
/> <code><br
/> macpro:bsd-port sam$ ./build/bsd-amd64/j2sdk-image/bin/java -version<br
/> openjdk version "1.7.0-internal"<br
/> OpenJDK Runtime Environment (build 1.7.0-internal-sam_2011_01_22_16_40-b00)<br
/> OpenJDK 64-Bit Server VM (build 20.0-b03, mixed mode)<br
/> </code><br
/> Now we want to build the Lambda compiler and runtime support:</p><ul><li>Grab the source:<br
/> <code>cd $OPENJDK_ROOT; hg clone http://hg.openjdk.java.net/lambda/lambda/langtools</code></li><li>Build the tools:<br
/> <code>cd $OPENJDK_ROOT/langtools; ant -Dboot.java.home=../bsd-port/build/bsd-amd64/j2sdk-image -f make/build.xml</code></li></ul><p>OpenJDK 7 doesn&#8217;t actually support everything that we need to run code generated for Lambda though. We need to also build a java agent that will modify the bytecodes in classes as they are loaded to run on the older VM for some features. Here is how you do that:</p><ul><li>Grab the source:<br
/> <code>cd $OPENJDK_ROOT; svn checkout http://jsr335-lambda.googlecode.com/svn/trunk/ jsr335-lambda</code></li><li><code>export JAVA_HOME=$OPENJDK_ROOT/bsd-port/build/bsd-amd64/j2sdk-image</code></li><li>Build the agent:<br
/> <code>cd jsr335-lambda/agent; ant jar</code></li><li><code>export AGENTJAR=$OPENJDK_ROOT/jsr335-lambda/agent/lib/jsr335-agent.jar</code></li></ul><p>Now we can actually build Lambda code and execute it, with a lot of command line options. For example, here is a simple program that we might want to execute:</p><pre>
public class Test {
  public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(#{ System.out.println("ran"); });
    t.start();
    t.join();
  }
}
</pre><p>Let&#8217;s first compile it:</p><ul><li><code>export PATH=$JAVA_HOME/bin:$PATH</code></li><li><code>export LANGTOOLS_JAR=$OPENJDK_ROOT/langtools/dist/lib/classes.jar</code></li><li><code>javac -J-Xbootclasspath/p:$LANGTOOLS_JAR -source 8 -target 8 Test.java</code></li></ul><p>Now we have Test.class file that will only work in a VM that supports some of the bytecode that we are using. In this case we don&#8217;t need the transformations so we can execute this code like this:<br
/> <code><br
/> macpro:jsr335 sam$ java -cp . Test<br
/> ran<br
/> </code><br
/> Here is some code that will not run out of the box, that shows you how you can now write extension methods:</p><pre>
public class Test2 {
  interface Trait {
    int inc(int i) default Test2.inc;
  }
  static int inc(Trait t, int i) { return i+1;}
  public static class Test3 implements Trait {}
  public static void main(String[] args) {
    Trait t = new Test3();
    System.out.println(t.inc(1));
  }
}
</pre><p>If you try and run this without the agent you will get this:<br
/> <code><br
/> macpro:jsr335 sam$ java -cp . Test2<br
/> Exception in thread "main" java.lang.AbstractMethodError: Test2$Test3.inc(I)I<br
/> at Test2.main(Test2.java:9)<br
/> </code><br
/> Now we execute with the agent enabled:<br
/> <code><br
/> macpro:jsr335 sam$ java -javaagent:$AGENTJAR -cp . Test2<br
/> 2<br
/> </code><br
/> The last feature that you might want to use, are method handles. Essentially you can convert a method handle into a closure by using it in a SAM context. Here is an example of how they work:</p><pre>
public class Test3 {
    public void test() {
	System.out.println("Test");
    }
    public static void main(String[] args) {
	Test3 t = new Test3();
	Runnable r = t#test;
	r.run();
    }
}
</pre><p>In order to run this we need to enable InvokeDynamic on our VM and include the classes from langtools for some runtime support:<br
/> <code><br
/> macpro:jsr335 sam$ java -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic -Xbootclasspath/p:$LANGTOOLS_JAR -javaagent:$AGENTJAR -cp . Test3<br
/> Test<br
/> </code><br
/> That command line has everything you should ever need to execute code generated using the Lamba enhancements so using anything else is probably unnecessary. Now let&#8217;s put all of this together into the final example from the Lambda proposal itself:</p><pre>
import java.util.*;
interface Sortable&lt;T, U extends Comparable&lt;? super U>>  extends List&lt;T>  {
   void sortBy(Extractor&lt;? super T, ? extends U>  e) default Impl.sortBy;
   static class Impl {
       public static&lt;T, U extends Comparable&lt;? super U>>
                 void sortBy(Sortable&lt;T, U>  sortable, final Extractor&lt;? super T, ? extends U>  e) {
           Collections.sort(sortable, #{T a, T b ->  e.extract(a).compareTo(e.extract(b))});
       }
   }
}
interface Extractor&lt;T,U> {
    public U extract(T t);
}
class Person {
    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    private String lastName;
    public String getLastName() { return lastName; }
    private String firstName;
    public String getFirstName() { return firstName;}
    public String toString() {
        return firstName + " " + lastName;
    }
}
public class Test4 {
    public static class SortableList&lt;T, U extends Comparable&lt;? super U>> extends ArrayList&lt;T> implements Sortable&lt;T, U> {}
    public static void main(String[] args) {
        Sortable&lt;Person, String> list = new SortableList&lt;>();
        list.add(new Person("Sam", "Pullara"));
        list.add(new Person("Brian", "Goetz"));
        list.add(new Person("Bob", "Lee"));
        list.sortBy(Person#getLastName);
        System.out.println(list);
    }
}
</pre><p>Which results in:<br
/> <code><br
/> macpro:jsr335 sam$ java Test4<br
/> [Brian Goetz, Bob Lee, Sam Pullara]<br
/> </code><br
/> The punchline is that if you read through all of this you get a bonus: here is the distribution of above build products that you can download and run on your Mac (assuming you are running a 64-bit build of snow leopard):</p><p><a
href="http://javarants.com/openjdk7-lambda-macosx-x86_64-01222010.zip">openjdk7-lambda-macosx-x86_64-01222010.zip</a></p> ]]></content:encoded> <wfw:commentRss>http://www.javarants.com/2011/01/22/using-closures-method-handles-and-extension-methods-in-java-8-jsr-335/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Testing out Percona and HandlerSocket with AvroBase</title><link>http://www.javarants.com/2010/12/20/testing-out-percona-and-handlersocket-with-avrobase/</link> <comments>http://www.javarants.com/2010/12/20/testing-out-percona-and-handlersocket-with-avrobase/#comments</comments> <pubDate>Mon, 20 Dec 2010 21:34:00 +0000</pubDate> <dc:creator>Sam Pullara</dc:creator> <category><![CDATA[Technology]]></category> <guid
isPermaLink="false">http://www.javarants.com/?p=1386</guid> <description><![CDATA[The great thing about the AvroBase interface is that it can be used with many different datastores because of its relatively low requirements on those stores. HandlerSocket is a plugin for MySQL that gives you direct access to the low &#8230; <a
href="http://www.javarants.com/2010/12/20/testing-out-percona-and-handlersocket-with-avrobase/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>The great thing about the <a
href="https://github.com/spullara/havrobase/blob/master/avrobase/src/main/java/avrobase/AvroBase.java">AvroBase</a> interface is that it can be used with many different datastores because of its relatively low requirements on those stores. <a
href="https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL">HandlerSocket</a> is a plugin for MySQL that gives you direct access to the low level APIs that let you do the operations that AvroBase requires without going through the high-level SQL APIs and therefore skip a lot of boilerplate parsing that happens for every single lookup or scan. You can read about the <a
href="http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html">HandlerSocket benchmarks here</a>. <a
href="http://www.percona.com/software/percona-server/">Percona Server</a> is just a better implementation of MySQL with its own modified InnoDB engine called XtraDB. In combination you should be able to get even higher numbers of transactions per second for individual servers in a cluster. Building it on the Mac (or any unix system) is pretty straight-forward.<br
/> <span
id="more-1386"></span><br
/> <code><br
/> cd /Users/sam/Software/Percona-Server-5.1.53/<br
/> ./configure --prefix=/Users/sam/usr<br
/> make &amp;&amp; make install<br
/> </code><br
/> Similarly, download the HandlerSocket source via Git and then build it:<br
/> <code><br
/> git clone https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL.git<br
/> cd HandlerSocket-Plugin-for-MySQL/<br
/> sh autogen.sh<br
/> ./configure --prefix=/users/sam/usr --with-mysql-source=/Users/sam/Software/Percona-Server-5.1.53 --with-mysql-bindir=/users/sam/usr/bin --with-mysql-plugindir=/users/sam/usr/lib/mysql/plugin<br
/> make &amp;&amp; make install<br
/> </code><br
/> You then need to make some changes to the my.cnf file:<br
/> <code><br
/> [mysqld]<br
/> user = sam<br
/> port = 3406<br
/> loose_handlersocket_port = 9998<br
/> loose_handlersocket_port_wr = 9999<br
/> loose_handlersocket_threads = 16<br
/> loose_handlersocket_threads_wr = 1<br
/> </code><br
/> Start up mysql for the first time:<br
/> <code><br
/> export PATH=~/usr/bin:$PATH<br
/> mysql_install_db<br
/> cd /Users/sam/usr ; /Users/sam/usr/bin/mysqld_safe &amp;<br
/> </code><br
/> Then connect to mysql and install the plugin:<br
/> <code><br
/> mysql -u root<br
/> install plugin handlersocket soname 'handlersocket.so';<br
/> </code><br
/> For AvroBase I am using the native i/o Java client:<br
/> <code><br
/> svn checkout http://hs4j.googlecode.com/svn/trunk/ hs4j<br
/> mvn install -Dmaven.test.skip=true<br
/> </code><br
/> Haven&#8217;t fully put it through its paces but I expect to do some benchmarking here shortly. Because of the amount of work to deserialize objects vs the database access my guess is that it won&#8217;t make a huge different in terms of qps for a single front-end. However, it will likely let us go to a much higher number of frontends before accessing the database becomes the bottleneck.</p> ]]></content:encoded> <wfw:commentRss>http://www.javarants.com/2010/12/20/testing-out-percona-and-handlersocket-with-avrobase/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>What does the Facebook security thing mean to users?</title><link>http://www.javarants.com/2010/10/19/what-does-the-facebook-security-thing-mean-to-users/</link> <comments>http://www.javarants.com/2010/10/19/what-does-the-facebook-security-thing-mean-to-users/#comments</comments> <pubDate>Tue, 19 Oct 2010 17:53:37 +0000</pubDate> <dc:creator>Sam Pullara</dc:creator> <category><![CDATA[Technology]]></category> <guid
isPermaLink="false">http://www.javarants.com/?p=1375</guid> <description><![CDATA[You might have read a lot about the Facebook issue over the last couple of days. The technical description of this is pretty complicated but the implications are pretty clear. When you use applications on Facebook and they use a &#8230; <a
href="http://www.javarants.com/2010/10/19/what-does-the-facebook-security-thing-mean-to-users/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>You might have read a lot about the Facebook issue over the last couple of days. The technical description of this is pretty complicated but the implications are pretty clear. When you use applications on Facebook and they use a technology called &#8216;iframes&#8217; to host their application (like Farmville) and then partner with other companies for advertising it is possible that your UID gets passed all the way from Facebook to the third-party advertising sites. This happens because of the details of how browsers work with referrers, third party javascript includes and iframes. At that point they could take that UID and set a cookie on your browser so that whenever they see you, wherever you are on the web, they know that it is you and can lookup your public Facebook information and use that information to target ads, customize content, etc.<br
/> <span
id="more-1375"></span><br
/> People can argue that this information is public, however, the fact that the information is tied to your browser and can be accessed anywhere that the advertiser has an ad makes it especially powerful. For example, I could use the information to create advertisements on another website (not Facebook) that includes photos of you and your friends. I could address you by name in the ad, use the names of your parents or children, whatever you might have made available on Facebook to the world at large. My Facebook account is pretty tied down, however there is a certain base level of publicness about Facebook that makes the possibility of creating very creepy, misleading ads across the internet.</p><p>Here is what I can discover about myself using only my UID and publicly accessible URLs via the Facebook Open Graph API:</p><p>Name: Sam Pullara<br
/> First Name: Sam<br
/> Last Name: Pullara<br
/> Link: http://www.facebook.com/spullara<br
/> Gender: Male<br
/> Locale: en_US<br
/> Picture: <img
src="http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs267.snc3/23103_2410418_4027_q.jpg" alt="" /></p><p>If you want to do the same and see what is available for you, start here https://graph.facebook.com/[your uid]?metadata=1 and try each of the links in the connections subsection to see what is easily available.</p><p>Using web scraping, I can discover even more information about me:</p><p><img
src="http://dl.dropbox.com/u/3924269/Screenshots/8.png"></p><p>It is a good thing for Facebook to not allow this kind of UID transfer to third parties with whom you have no connection, especially when cookies are involved. Other large scale internet services go to great lengths to avoid this kind of data transfer. Facebook should fix the URLs so it isn&#8217;t inadvertently transferred from their application partners to the application partner&#8217;s advertisers.</p> ]]></content:encoded> <wfw:commentRss>http://www.javarants.com/2010/10/19/what-does-the-facebook-security-thing-mean-to-users/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>HAvroBase: a searchable, evolvable entity store on top of HBase and Solr</title><link>http://www.javarants.com/2010/06/30/havrobase-a-searchable-evolvable-entity-store-on-top-of-hbase-and-solr/</link> <comments>http://www.javarants.com/2010/06/30/havrobase-a-searchable-evolvable-entity-store-on-top-of-hbase-and-solr/#comments</comments> <pubDate>Wed, 30 Jun 2010 19:55:44 +0000</pubDate> <dc:creator>Sam Pullara</dc:creator> <category><![CDATA[Java]]></category> <category><![CDATA[Startup]]></category> <category><![CDATA[Technology]]></category> <guid
isPermaLink="false">http://www.javarants.com/?p=1349</guid> <description><![CDATA[Building out a social consumer internet product that could change quickly and evolve over time puts special requirements on the underlying data store. You need to be prepared for scale but not investing too much too early, your business may &#8230; <a
href="http://www.javarants.com/2010/06/30/havrobase-a-searchable-evolvable-entity-store-on-top-of-hbase-and-solr/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Building out a social consumer internet product that could change quickly and evolve over time puts special requirements on the underlying data store. You need to be prepared for scale but not investing too much too early, your business may need to pivot in different directions so data models can&#8217;t be set in stone and you need to be able to search that data to enable many of the features users expect from an online social product. I have the additional requirement that I wanted all the entities in the system, regardless of where they are stored, to be accessed the same way and be described by the same data description language for consistency and maintainability. I&#8217;ve created what I think to be a novel solution to these requirements in the form of <a
href="http://github.com/spullara/havrobase">HAvroBase</a>.<span
id="more-1349"></span></p><p>The first choice you have to make against these requirements is which data definition language are you going to use? Instead of depending on the native format of the storage system I&#8217;ve decided to use <a
href="http://github.com/apache/avro">Avro</a>. Similar to <a
href="http://code.google.com/p/protobuf/">Protocol Buffers</a> and <a
href="http://incubator.apache.org/thrift/">Thrift</a>, Avro lets you define your entities using schemas and store them efficiently in a binary format. Additionally, as long as you have the original schema available you can load old data into a new schema. This will let you evolve your stored rows lazily and not have to completely update your storage system when a new field is added or a field is removed.</p><p>Whereas the data definition choice is basically commodity at this point and your choice can be somewhat arbitrary, the choice of storage technology will likely be something that has more trade-offs to consider. After looking at the features and communities of a variety of projects including <a
href="http://hbase.apache.org/">HBase</a>, <a
href="http://cassandra.apache.org/">Cassandra</a>, <a
href="http://code.google.com/p/redis/">Redis</a>, <a
href="https://wiki.basho.com/display/RIAK/Riak">Riak</a>, <a
href="http://mysql.com">MySQL</a>, <a
href="http://www.northscale.com/products/membase_server.html">Membase</a>, <a
href="http://www.terracotta.org/">Terracotta</a>, etc. I finally chose HBase for a few reasons that may not be that important to you. First I settled on a <a
href="http://labs.google.com/papers/bigtable.html">BigTable</a> type choice based on the data model. That left HBase and Cassandra as contenders. There also a few things I think are advantages:</p><ul><li>multiple tables</li><li>better ordered key support</li><li>Zookeeper and HDFS were already in my solution</li><li>Hive and Hadoop support against the native data format</li><li>consistency</li><li>compare and set</li><li>atomic increment</li><li>versioning</li></ul><p><span
style="font-family: Georgia, 'Bitstream Charter', serif; line-height: 24px; font-size: 16px;">Cassandra definitely has its own advantages that didn&#8217;t out-weigh the other considerations including</span></p><ul><li>performance</li><li>simple deployment</li><li>always writable</li></ul><p><span
style="font-size: medium;"><span
style="line-height: 24px;">You might make different tradeoffs or even use both solutions for different problems. I&#8217;m also biased somewhat as I am sharing an office with <a
href="http://cloudera.com/">Cloudera</a> and get top notch support at a moments notice.</span></span></p><p><span
style="font-size: medium;"><span
style="line-height: 24px;">Whether I chose HBase or Cassandra the implementation would have been much the same and with the HAvroBase framework you can have multiple independent storage systems. The framework does somewhat shield you from this decision, at least in your code.</span></span></p><p><span
style="font-size: medium;"><span
style="line-height: 24px;">When it comes to text search you really don&#8217;t get better than <a
href="http://lucene.apache.org/">Lucene</a> in open source and the features that <a
href="http://wiki.apache.org/solr/FrontPage">Solr</a> builds on top of Lucene make it even better. I don&#8217;t think there is reasonable argument for using something besides Solr at this point. Especially with their support for sharding and replication that comes with <a
href="http://wiki.apache.org/solr/SolrCloud">Solr Cloud</a>. It also has the nice benefit that it supports multiple tables, like HBase, so I can efficiently separate entities and allow them to scale independently without managing an additional system.</span></span></p><p><span
style="font-size: medium;"><span
style="line-height: 24px;">The last choice that I made was runtime configuration. There are a few solutions including <a
href="http://www.springsource.org/">Spring</a>, <a
href="http://code.google.com/p/google-guice/">Guice</a> and rolling my own and I finally landed on the side of Guice. I just like typed, programmatic configuration better than XML files and since that is the focus of Guice, I think it is the best solution for that.</span></span></p><p><span
style="font-size: medium;"><span
style="line-height: 24px;">The first thing that you need to do to use the system is to define an entity in Avro:</span></span><br
/> <script src="http://gist.github.com/484813.js"></script><br
/> <span
style="font-size: small;"><span
style="font-size: medium;"><span
style="line-height: 24px;">You can use the Avro compiler (or the Maven plugin) to convert that definition to classes (HAvroBase requires this). Then you do the typical things in code to setup your HBase connection but within a Guice module and set some of the configuration parameters for HAB:</span></span></span><br
/> <script src="http://gist.github.com/484810.js"></script><br
/> <span
style="font-size: small;"><span
style="font-size: medium;"><span
style="line-height: 24px;">That configuration can then be used to instantiate an instance of the HAB class that implements the connection to HBase like this:</span></span></span><br
/> <script src="http://gist.github.com/484815.js"></script><br
/> <span
style="font-size: small;"><span
style="font-size: medium;"><span
style="line-height: 24px;">You&#8217;ll notice that configuration is somewhat split between things that the base system needs to know and things that the HAB needs to know. For example, what table the schema is store in isn&#8217;t relevant to the base system as an implementer is free to store schemas however they like. But the assumption is that every system will have the concept of a table and a column family in order to separate entities in the underlying storage system. The Solr support is pretty elegant I think. Rather than specifying in more than one place which fields should be indexed, instead at runtime it queries the Solr core&#8217;s schema.xml that defines them and then when you put an entity in the system it automatically indexes those fields.  Here is an example of using some of the APIs:</span></span></span><br
/> <script src="http://gist.github.com/484816.js"></script><br
/> This example creates a new User, puts it into the HAvroBase, looks it up by row and then searches for it by field that is indexed and finally deletes it. In any fully implemented AvroBase system this should work identically. You&#8217;ll notice in the memcached implementation that only put/get/delete are implemented and it doesn&#8217;t support scan or search at all. I&#8217;ve considered breaking out that functionality into separate interfaces but haven&#8217;t done that yet.</p><p>If you are unhappy with the way the default Avro compiler generates code you can use my <a
href="http://github.com/spullara/avrocompiler">templated Avro compiler</a> that lets you change the generated code. I have done that for my project to make them a little more developer friendly.</p><p>Things left to do:</p><ul><li>implement guarantees around indexing</li><li>optimize schema keys (use an abbrev table instead of a hex sha-256 key)</li><li>indexing nested fields and arrays in Solr</li></ul><p>I&#8217;m sure there are more things left undone but those are some of the more obvious issues.</p> ]]></content:encoded> <wfw:commentRss>http://www.javarants.com/2010/06/30/havrobase-a-searchable-evolvable-entity-store-on-top-of-hbase-and-solr/feed/</wfw:commentRss> <slash:comments>17</slash:comments> </item> <item><title>Android Dalvik VM performance is a threat to the iPhone</title><link>http://www.javarants.com/2010/05/26/android-dalvik-vm-performance-is-a-threat-to-the-iphone/</link> <comments>http://www.javarants.com/2010/05/26/android-dalvik-vm-performance-is-a-threat-to-the-iphone/#comments</comments> <pubDate>Wed, 26 May 2010 16:29:57 +0000</pubDate> <dc:creator>Sam Pullara</dc:creator> <category><![CDATA[Apple]]></category> <category><![CDATA[Java]]></category> <category><![CDATA[Technology]]></category> <guid
isPermaLink="false">http://www.javarants.com/?p=1311</guid> <description><![CDATA[One of the peculiarities of Apple is that they have set themselves down a path where every Apple developer needs to learn Objective-C (and C/C++) to build applications for their platform.  The biggest characteristic of Objective-C vs Java is dynamic &#8230; <a
href="http://www.javarants.com/2010/05/26/android-dalvik-vm-performance-is-a-threat-to-the-iphone/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>One of the peculiarities of Apple is that they have set themselves down a path where every Apple developer needs to learn Objective-C (and C/C++) to build applications for their platform.  The biggest characteristic of Objective-C vs Java is dynamic dispatch. At runtime Objective-C can send arbitrary messages to objects and they may or may not respond to them.  This has the nice property that you can write code that is very dynamic and loosely bound but it also has the property that method calls in Objective-C are very slow and the more code that you write in Objective-C instead of in C/C++ the slower your codebase becomes.  Up until Android 2.2 (Froyo) the JVM (really a <a
href="http://en.wikipedia.org/wiki/Dalvik_(software)">Dalvik JVM</a> for licensing reasons) on the Android platform was playing with one hand tied behind its back.  Different from desktop/server Java, the JVM was still an interpreter, like the original JVM back in the Java 1.0 days.  It was very efficient interpreter but an interpreter none-the-less and was not creating native code from the Dalvik bytecodes that it uses.  As of Android 2.2 they have added a JIT, a just-in-time compiler, to the stack that translates the Dalvik bytecode into much more efficient machine code much like a C/C++ compiler.  You can see the results of this in the benchmarks of Froyo which <a
href="http://crave.cnet.co.uk/mobiles/0,39029453,49305763,00.htm">show a 2-5x improvement</a>.  As they add more and more JIT and GC features that have appeared in HotSpot, JRockit, etc, you will likely see even more improvements over time &#8212; without having to change or recompile the 3rd party developed software.</p><p><span
id="more-1311"></span></p><p>This wouldn&#8217;t be that big a deal if Android software wasn&#8217;t already approaching the speed of the Apple iPhone even when running its applications through the interpreter (see the HTC EVO 4G running 2.1).  This is likely going to mean that 3rd party developer applications created for Android, running on the same hardware, is going to be faster than the same code written against the Objective-C libraries that Apple provides for the iPhone.  You&#8217;ll be able to get more done, have smoother user interfaces and all around build more powerful applications easier.  A better experience for the user and the developer on Android is a bad thing for Apple.</p><p>The final issue that Apple has is that far more people know and need  to know Java than Objective-C.  Except for their platform, there is no need to ever learn it.  The tool chain is much more robust, information is much easier to come by, garbage collection is available, and there are thousands more libraries written in Java than Objective-C and far more portable libraries than are written for C/C++.  You might argue that you can always drop down to C/C++ code to make up for the lost performance of using Objective-C (at a significant cost development-wise).  You can do that, except places where you need to make a call into Apple&#8217;s Objective-C runtime libraries or where you want to write callbacks from those libraries. Those are mostly Objective-C libraries and use the dynamic dispatch mechanism which <a
href="http://www.javarants.com/2004/05/04/looks-like-apple-should-switch/">I showed in 2004 was very much slower than Java</a>.  I&#8217;d really love to see the whole <a
href="http://shootout.alioth.debian.org/">computer language shootout</a> written with Objective-C calling conventions just to show how much slower it is at that level.</p><p>Obviously performance is not the only consideration, but it is a big one.  Android has other issues like a fragmented operating system base, hardware feature base and a more complicated user experience.  All those things will conspire to hold it back but I think we can see the writing on the wall that Android is going to dominate iPhone market-share wise which will eventually make it a more attractive platform business-wise.</p><p><strong>Update: </strong>Just so people don&#8217;t get the wrong idea, I am a rabid iPhone user and develop for the iPhone first.  This blog entry is to call out a threat that Apple should take seriously.</p><p><strong>Update 2: </strong>Alright, you win. Don&#8217;t worry about competing with Google &amp; Android on performance. It probably doesn&#8217;t matter that much for the user experience.  Especially don&#8217;t fix obj_msgSend() with a JIT/LLVM, that would be crazy.</p> ]]></content:encoded> <wfw:commentRss>http://www.javarants.com/2010/05/26/android-dalvik-vm-performance-is-a-threat-to-the-iphone/feed/</wfw:commentRss> <slash:comments>90</slash:comments> </item> <item><title>Off-loading real work to YQL instead of using your server</title><link>http://www.javarants.com/2010/05/22/off-loading-real-work-to-yql-instead-of-using-your-server/</link> <comments>http://www.javarants.com/2010/05/22/off-loading-real-work-to-yql-instead-of-using-your-server/#comments</comments> <pubDate>Sun, 23 May 2010 01:23:24 +0000</pubDate> <dc:creator>Sam Pullara</dc:creator> <category><![CDATA[Technology]]></category> <category><![CDATA[yahoo]]></category> <guid
isPermaLink="false">http://www.javarants.com/?p=1305</guid> <description><![CDATA[Just saw a cool blogpost about summing up all your subscribers on RSS, Facebook and Twitter. The only issue is that it requires PHP to work. I decided to quickly rewrite it as a YQL Execute table instead. So rather &#8230; <a
href="http://www.javarants.com/2010/05/22/off-loading-real-work-to-yql-instead-of-using-your-server/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Just saw a cool <a
href="http://tutorialzine.com/2010/05/showing-facebook-twitter-rss-stats-jquery-yql/">blogpost about summing up all your subscribers on RSS, Facebook and Twitter</a>.  The only issue is that it requires PHP to work. I decided to quickly rewrite it as a YQL Execute table instead.  So rather than write that code in PHP, here is the <a
href="http://javarants.com/yql/stats.xml">code for my table</a>.  Pretty simple. You pass it a URL for Feedburner, an id for Facebook and an id for Twitter and it generates some simple HTML for you to display as a widget.</p><p>The html page that he uses didn&#8217;t have to be changed that much, you can find the same demo that he uses <a
href="http://javarants.com/subscriberdemo.html">here</a>.  This was really quick so right now there is no way to leave out one without it freaking out.  This is more a tech demo than it is a real solution.</p> ]]></content:encoded> <wfw:commentRss>http://www.javarants.com/2010/05/22/off-loading-real-work-to-yql-instead-of-using-your-server/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Maven artifacts need to be more discoverable</title><link>http://www.javarants.com/2010/05/16/maven-artifacts-need-to-be-self-discoverable/</link> <comments>http://www.javarants.com/2010/05/16/maven-artifacts-need-to-be-self-discoverable/#comments</comments> <pubDate>Mon, 17 May 2010 01:04:17 +0000</pubDate> <dc:creator>Sam Pullara</dc:creator> <category><![CDATA[Java]]></category> <category><![CDATA[Technology]]></category> <guid
isPermaLink="false">http://www.javarants.com/?p=1302</guid> <description><![CDATA[The laundry list of repositories that are filling the POM in Maven projects has to go. The ideal of having a central store of all artifacts is clearly dead and we have to move on. My proposal is two fold. &#8230; <a
href="http://www.javarants.com/2010/05/16/maven-artifacts-need-to-be-self-discoverable/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>The laundry list of repositories that are filling the POM in Maven projects has to go.  The ideal of having a central store of all artifacts is clearly dead and we have to move on.  My proposal is two fold.  First, the repository to end all repositories that doesn&#8217;t actually store the files but simply redirects to a known good location for the group id / artifact id / version combination.  The second is that we create an ad hoc standard for artifact discovery based on the group id.  For example, if the group id is com.sampullara.cli-parser then you should be able to find a repository that stores all artifacts at <a
href="http://cli-parser.sampullara.com/repository/">http://cli-parser.sampullara.com/repository/</a>.  Perhaps we could even put some sort of discovery file at the root to find them.  This would allow anyone to distribute Maven artifacts to developers without having to publish to any central location.  It would also drastically reduce the amount of repository cruft that is creeping into so many of the POM files I have seen recently.  Further, it would make it really easy for github, googlecode, apache, etc to help their developers automatically publish with just the right naming conventions in place.</p><p>Come to think of it, maybe the whole thing is a little suspect.  Maybe we should have been using URLs the entire time.  How much value are we getting out of the layer of indirection?  This is intended to be a discussion&#8230;</p> ]]></content:encoded> <wfw:commentRss>http://www.javarants.com/2010/05/16/maven-artifacts-need-to-be-self-discoverable/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>How Facebook could open the Open Graph APIs</title><link>http://www.javarants.com/2010/05/12/how-facebook-could-open-the-open-graph-apis/</link> <comments>http://www.javarants.com/2010/05/12/how-facebook-could-open-the-open-graph-apis/#comments</comments> <pubDate>Wed, 12 May 2010 21:24:31 +0000</pubDate> <dc:creator>Sam Pullara</dc:creator> <category><![CDATA[Technology]]></category> <guid
isPermaLink="false">http://www.javarants.com/?p=1297</guid> <description><![CDATA[I was pondering how Facebook could really answer it's critics in a profound way that would really up-level the social fabric of the internet while also satisfying those that want ultimate control over their data. <a
href="http://www.javarants.com/2010/05/12/how-facebook-could-open-the-open-graph-apis/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>I was pondering how Facebook could really answer it&#8217;s critics in a profound way that would really up-level the social fabric of the internet while also satisfying those that want ultimate control over their data.  The basic premise of the solution would be to allow any node in the <a
href="http://developers.facebook.com/docs/api">Open Graph</a> to be redirected to a 3rd party developers server.  From that point on, Facebook would then treat that node just as if they were a developer that current gets access to Facebook users.<br
/> <span
id="more-1297"></span><br
/> For example, my URL is currently:</p><p><a
href="http://graph.facebook.com/2410418">http://graph.facebook.com/2410418</a></p><p>If I could easily go to my account and specify a new location for that data, for example, maybe I would put it at:</p><p><a
href="http://graph.javarants.com/me">http://graph.javarants.com/me</a></p><p>Which, for the sake of argument, resolves to much the same information about me, the Sam Pullara node in the graph.  Similarly you could ask for metadata about what other things are available. Since it is a REST API you could mix and match those links to point to different endpoints.  Some of them might point to a new Flickr Open Graph API endpoint that responds with my photos that are available to the caller.  Another might point back at Facebook for my social graph.  While a 3rd could point at a web service (say a new output format for Y! Pipes) that combines my posts on Facebook with my RSS feed and my Twitter feed in order to populate the &#8216;posts&#8217; endpoint.  Using these endpoints Facebook could construct the same set of views they have today on the graph but without being the ultimate authority for the data itself.  Plus, as they would have to call your APIs with the authentication of the viewing part, privacy is under your complete control as well.  For performance reasons, you could still have caching and asynchronous notification systems. Perhaps with some special sauce for websocket you could even allow them to reference the client browser rather than another server for ultimate end user control.</p><p>It would be theoretically possible to implement this now without Facebook&#8217;s involvement but without them as one of the providers I don&#8217;t think you could really get the adoption that would make this truly revolutionary.</p> ]]></content:encoded> <wfw:commentRss>http://www.javarants.com/2010/05/12/how-facebook-could-open-the-open-graph-apis/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>The ideal web application templating system</title><link>http://www.javarants.com/2010/05/03/the-ideal-web-application-templating-system/</link> <comments>http://www.javarants.com/2010/05/03/the-ideal-web-application-templating-system/#comments</comments> <pubDate>Mon, 03 May 2010 16:47:05 +0000</pubDate> <dc:creator>Sam Pullara</dc:creator> <category><![CDATA[Technology]]></category> <guid
isPermaLink="false">http://www.javarants.com/?p=1295</guid> <description><![CDATA[When a designer and a developer work together to create an HTML web application one of the biggest issues is how you translate their vision into code in a way that allows for iteration and flexibility when those designs change. <a
href="http://www.javarants.com/2010/05/03/the-ideal-web-application-templating-system/">Continue reading <span
class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>When a designer and a developer work together to create an HTML web application one of the biggest issues is how you translate their vision into code in a way that allows for iteration and flexibility when those designs change.  Another issue is that while you are testing a design you would like it to be filled with actual data but having it hooked up to a live server at all times is very painful.  So far I haven&#8217;t found a system that really gives me even these attributes and as it turns out there are more requirements that I would like that are also mostly unfulfilled.  Here is a list of requirements I would like to see met by a templating system:</p><ul><li>Works well with HTML5/CSS3 progressive enhancement</li><li>Allows mock data within the template that is replaced at runtime</li><li>Client-side version that leverages the mock data for shift-reload debugging</li><li>Composable components, not monolithic pages</li><li>Very little or no business logic in the templates</li><li>Concurrent evaluation possible</li></ul><p>Right now I am looking at <a
href="http://github.com/janl/mustache.js/">mustache.js</a> and its various server-side implementations as a possible solution to this.  It has many of those qualities but I would likely need to make some of my own modifications for things like concurrent evaluation.</p><p>Any suggestions?</p> ]]></content:encoded> <wfw:commentRss>http://www.javarants.com/2010/05/03/the-ideal-web-application-templating-system/feed/</wfw:commentRss> <slash:comments>12</slash:comments> </item> </channel> </rss>
