Pages

Monday, June 7, 2010

Snapshots of Wave Robot API Now Available

I've Mavenized the Wave Robot API and the Wave model portion of Wave Protocol, a dependency of Wave Robot API and deployed snapshots to my public repository. Currently, I've only deployed snapshots since the use of this artifact is completely untested. I'm working on creating a Maven archetype for Wave robots (which will use this repository until Google uploads it somewhere), and an example using the archetype. After I've done this and am sure it works (and that I haven't done anything stupid with Maven), then I will tag a release and put it on my release repository.

If anyone would like to try it out in the mean time, your feedback would be most appreciated! Here is what you would need in your pom.xml:

<dependencies>
    <dependency>
        <groupId>com.google.wave</groupId>
        <artifactId>wave-robot-api</artifactId>
        <version>20100408-SNAPSHOT</version>
    </dependency>
</dependencies>
<repositories>
    <repository>
        <id>public-repo_maven2-repository</id>
        <url>http://public-repo.googlecode.com/svn/repository/</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <releases>
            <enabled>true</enabled>
        </releases>
    </repository>
    <repository>
        <id>public-repo_maven2-snapshots</id>
        <url>http://public-repo.googlecode.com/svn/snapshots/</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>
</repositories>

Some stuff I picked up along the way:
  • When using the WebDAV wagon with Google Code, make sure you use https, otherwise you're liable to get a 405 method not allowed error on a deploy.
  • There's an interesting bug with the Robot API's EventSerializerTest. The behavior is different in Javac 1.5 vs 1.6 but compile fine with the Eclipse compiler. There is bug report for Javac here (fixed in 1.7). I opened a ticket for Google to explicitly cast this in the method so the compiler doesn't have to do any inference, so that way it will build fine with Javac even if they're using JDK 1.6. In the mean time, I've opted to use the Eclipse compiler in the pom rather than altering my local copy of the source. My goal is to make this an exact match to the class files in the zip they've distributed.
  • Guava, the successor to Google Collections (as a backwards compatible superset) and dependency of the Wave model API is on Maven central, but not on Google's repository. It's a little odd, but shouldn't cause any issues.

A special thanks to Jurgen and commenters for the helpful post that got me started.

Friday, June 4, 2010

Bots updated to v2 API

I've updated WorldCat-Bot and Yodaspeakify to v2 of the Wave API, which boasts some fantastic new features, including an easier way to do annotations, doing away with Cron, no need for a separate profile servlet, and the capabilities.xml is automatically generated for you using annotations.

One thing I voted for as an improvement was to use regular expressions in this method. I'm not sure what the author of the issue was talking about with iterating over Elements since, as I understand, these don't include text. The artifacts are still not on Google's repository and I'm getting pretty tired of a 5 minute commit time when I change some jars around.  I'm working on using Google Code as a repository and adding these artifacts after I mavenize them, then I'll create archetypes for Wave -- watch for an update on this soon, now that my bots are done this is the next project.

Some snags I ran into:
The .replace() of BlipContentRefs doesn't work the way you'd think it would. I thought I could do
BlipContentRefs content = blip.first(originalText).replace(newText);
But the BlipContentRefs will be empty. I got a hint for how to do this from wadrobotframework's BlipUtils:
public static void replaceBlipContent(Blip bleep, String nextContent) {
    BlipContentRefs bcr = bleep.all();
    if (bcr != null) {
        bcr.delete();
        bleep.append(nextContent);
    }
}
Thanks, wadael!

Another issue was when I used DocumentChangedEvent and then did a .getBlip() it would return a null Blip. My understanding of the JavaDoc was that it would return the root blip if no Blip was associated with that event, but this didn't seem to be happening. So, I opted for a BlipSubmittedEvent instead. Which, now that I think about it, is probably the desired behavior anyway.

Another issue was when I was trying to take advantage of the cool new filtering options. WorldCat-Bot used to surround it's searches with angle brackets (<>), but when I tried to filter on this
@Capability(filter = "<.*>")
@Override
public void onDocumentChanged(DocumentChangedEvent event) {
  ...
}
It didn't work because the capabilities.xml that was generated was not well formed. I also tried the escaped version
@Capability(filter = "&lt;.*&gt;")
@Override
public void onDocumentChanged(DocumentChangedEvent event) {
  ...
}
But this didn't work either, it looked for the entire literal not the unescaped form. I don't think this is currently possible to do, so I now use square brackets ([]) to filter on.

While trying to debug this, I set up logging (GAE supports JUL), but I learned it only logs things with INFO, WARN, and SEVERE levels (though I couldn't get INFO to work even with the logging.properties file with .level = ALL. Maybe something else is misconfigured).

But overall, the new API has been a very positive experience.

Wednesday, June 2, 2010

GMaven & source encodings

I'm re-posting this because I made some more discoveries after I had initially posted it.

I discovered apparently SourceEncoding is completely broken in GMaven. I tried on Linux where the platform default encoding is UTF-8 and on Windows XP where the platform default encoding is Windows-1252. In both cases, it used ISO-8859-1 as the encoding of the class file it generated, despite the fact the source was encoded in the platform default encoding. I tested this with version 1.2 of the plugin and Groovy 1.7.0. Why this is happening makes no sense to me; I could understand if it used the platform default...but why always ISO-8859-1? I think this is the Jira for this: http://jira.codehaus.org/browse/GMAVEN-13.
I find it shockingly disappointing that a 'critical' issue can go unassigned for almost an entire year. I wonder if it is working in Ant. Their documentation seems to suggest that it does. If that's true, it might tell us something about where the Groovy team's priorities are.

In practice, this often is not problem, since if you're only using ASCII characters in your source code, the first 128 bytes have identical mappings in UTF-8, ISO-8859-1, and Windows-1252, so it won't matter which of those the plugin tries to use. However, I view this as a major obstacle to Groovy's gaining dominance, as it should support Maven (since for better or worst it's become the leading standard) and it should support encodings to support global growth.

Am I missing something? Any good workarounds? I'm also happy to share my experiment project with anyone who wants to play with it.

I've also discovered yet another way in which GMaven's documentation is fail. I was trying to get my project to work with the latest version of Groovy, when I came across this unrelated StackOverflow discussion which use the new 1.2 version of the plugin (which isn't in the archetype or anywhere documented as released -- I thought the artifacts were released by mistake since nothing has even been tagged in their repository for 1.1 or 1.2, although IntelliJ already supports it, plus nabble and some blogs talk about it so I guess it is released). Here are the needed bits from the pom:
<dependencies>
    <dependency>
        <groupId>org.codehaus.gmaven.runtime</groupId>
        <artifactId>gmaven-runtime-1.7</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>1.7.0</version>
    </dependency>
<dependencies>
<plugins>
    <plugin>
        <groupId>org.codehaus.gmaven</groupId>
        <artifactId>gmaven-plugin</artifactId>
        <version>1.2</version>        
        <configuration> 
            <providerSelection>1.7</providerSelection>         
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>generateStubs</goal>
                    <goal>compile</goal>
                    <goal>generateTestStubs</goal>
                    <goal>testCompile</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3</version>
        <configuration>
            <source>1.6</source>
            <target>1.6</target>
        </configuration>
    </plugin>
</plugins>

Update: According to this Jira, this is fixed in the 1.3 release. And it appears from my tests that this is the case.

Friday, May 28, 2010

Firefox vs Chrome Performance: A language difference?

Like many folks, I've been pretty blown away by the speed of Chrome (especially with respect to running JavaScript intensive sites). Currently, I use both Firefox and Chrome (depending on what I'm doing), but primarily Firefox as there are still some addons I can't live without.

Though I am excited to see the Out Of Process (OOP) Electrolysis project (which is now in beta) and the upcoming JägerMonkey JavaScript engine, I've begun to wonder if some of the performance differences we're seeing are more deeply rooted. Now I do know there are things that are supposedly not possible with Chrome's extension support, and of course with greater functionality comes reduced performance. But I've lately been wondering if the differences are at the language level. Does the language each was written in greatly alter performance? Have a look at this graphic
Source: Ohloh

Just look at all that JavaScript! While some sources favor JavaScript as a "first-class language" (and maybe I'm misinterpreting their meaning here), I'm not convinced that makes sense for desktop applications. There are some advantages to having portions of Firefox be in a web language, it makes it easy for web developers to extend & theme. But I'm not sure it makes sense to use it as extensively as they appear to have done.

For example, it would seem that the addon manager (nsExtensionManager.js) and session storage (sessionStore.js) are both JavaScript. How do I know these are their names? I didn't look at the code, but apparently I was putting Firefox under a bit too much pressure and I got the message saying these scripts had stopped responding (not at the same time). (Though this does happen less often with my portable Firefox, so maybe I need to clear out the profile).

It will of course help when we have the content and the UI in separate processes, and maybe help some more when Firefox gets a faster JavaScript engine, but I wonder if you can ever get really good performance from a language like JavaScript. I'm not saying to write the thing in assembly, I'm just saying maybe it makes sense to write the lower level components in a lower level language. What do you think?

As two somewhat unrelated sidenotes: What do you think the impact on Firefox's future will be with the loss of their tech lead? And do you think Google will finance Mozilla now that they're in some competition with each other?

Friday, May 21, 2010

Syntax Highlighting in Blogger: Round 2

So I'm now able to use the popular SyntaxHighlighter that most blogs use. I don't know what was stopping me before: maybe I've gone up in intelligence or they've fixed some bug. There's excellent instructions here. I think I'm going to make the move to this, since it's easier to read, has more features, and is more standard that the Prettify script I was using before. And one additional nice feature is I don't have to manually set my style="overflow:auto;", instead I just do
<pre class="brush:xml; wrap-lines:false">
And there's no longer a need to do an onLoad in the body tag, and a Groovy brush!
I've gone back to old posts and switched the styles, let me know if I've missed any.

Edit: Actually I think maybe the reason was my own lack of attention. I think I forgot to add 'alexgorbatchev.com' to NoScript's whitelist, and that's the host the scripts are currently hosted on, and it magically started working for me because I was in Chrome instead of Firefox. Doh! ... Doh? Who knows for sure?

Edit: The instructions aren't really up to date anymore, as new brushes have been added. Here is an updated example (note this uses the default theme, but you can choose to use other themes):
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushAS3.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushColdFusion.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDelphi.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushErlang.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushGroovy.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJavaFX.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPowerShell.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushScala.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
<script language='javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
This still goes inside the header area of the template, which means you'll still need to manually edit the HTML.

OK Maven, You Win

So, I've tried every combination of dependencySets, fileSets, and copyDependencies I could think of, nothing I did seems to work. All I wanted was to have a runnable jar with its dependencies in unexploded jars (something I've done before when making a jar by hand, although I used the default package in that case, not sure if that makes a difference). When I failed in this, I tried to have a runnable jar with its dependencies exploded into a lib directory. I failed in this as well. The only thing that seems to work is to have everything exploded into the same level. I tried this briefly with the shade plugin, but have mostly been trying with the assembly plugin. I give up, Maven. You win.
I've seen this mentioned fairly often on the web. If someone has a working example of a Groovy project compiled into a runnable uber-jar, I'd love to see it.

Friday, February 26, 2010

Workaround for JRA-19248: 401 on Jira Gadgets

Here is a workaround for JRA-19248: Dashboard widgets fail with HTTP 401 malformed security token, when left unattended for some time. Set the 'Refresh Interval' on the gadgets to 1hr (or less).  It's worked for me so far.
Edit: Well, it worked for several days, but apperently 1hr wasn't quite often enough. I'm trying with 30min, someone else reported having to use 15min. One more thing to note is that this issue is fixed with Jira 4.1.