Tuesday, September 22, 2009

Screenshot of Web Page in Python - 15 lines of code

I cant say that this solution is pretty elegant, but it's short and working. But... platform dependent, because of IE. Anyway here it is :

from win32com.client import Dispatch
from time import sleep
from sys import exit
import ImageGrab

IE.fullScreen = 1
while (IE.ReadyState != 4):
img = ImageGrab.grab((0, 0, 1440, 900))

Code is pretty simple- it launches IE in full screen mode, waiting while page being loaded, makes screenshot of whole screen resolution - 1440 x 900 in my case, and happily exits.

Tuesday, August 25, 2009

Spring BlazeDS integration - playing with testdrive

svn checkout https://src.springframework.org/svn/spring-flex/trunk/spring-flex-samples/

cd spring-flex-samples\spring-flex-testdrive,

mvn install

[INFO] -------------------------------------
[INFO] Java heap space
[INFO] -------------------------------------
[INFO] Trace
java.lang.OutOfMemoryError: Java heap space

Oops... Okay... lets say "set MAVEN_OPTS=-Xmx1024m" - should be enough.

mvn clean install

Not all is clear here, still :
1) org.springframework.flex:spring-flex:jar:1.0.1.BUILD-SNAPSHOT

Try downloading the file manually from the project website.

Then, install it using the command:
mvn install:install-file -DgroupId=org.springframework.flex -DartifactId=spring-flex -Dversion=1.0.1.BUILD-SNAPSHOT -Dpack
aging=jar -Dfile=/path/to/file

Alternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=org.springframework.flex -DartifactId=spring-flex -Dversion=1.0.1.BUILD-SNAPSHOT -Dpackag
ing=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]

Path to dependency:
1) org.springframework.flex.samples:testdrive:war:1.0.1.BUILD-SNAPSHOT
2) org.springframework.flex:spring-flex:jar:1.0.1.BUILD-SNAPSHOT

cd testdrive, edit pom.xml, change version of spring-flex jar:

mvn install
[INFO] --------------------------------
[INFO] Total time: 4 minutes 50 seconds

Cool, but not yet...

org.springframework.beans.factory.BeanCreationException: Error creating bean with name '_messageBrokerDefaultHandlerMapping': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '_messageBroker': Invocation of init method failed; nest ed exception is java.lang.NoClassDefFoundError: org/apache/xpath/CachedXPathAPI

Well, ok, org.apache.xpath.CachedXPathAPI - it's xalan

Then ... mvn install

Yahoooo !

[INFO] ------------------------------------------
[INFO] Total time: 7 minutes 30 seconds
[INFO] Finished at: Tue Aug 25 11:10:46 EEST 2009
[INFO] Final Memory: 32M/106M

Deploying.. looks nice...
FF -> http://localhost:8080/testdrive/insync01/insync01.html

Ooops... Flash-plugin stacktrace :

[RPC Fault faultString="Send failed" faultCode="Client.Error.MessageSend" faultDetail="Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Status 404: url: 'http://localhost:8080/messagebroker/amf'"]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultHandler()
at mx.rpc::Responder/fault()
at mx.rpc::AsyncRequest/fault()
at mx.messaging::ChannelSet/faultPendingSends()
at mx.messaging::ChannelSet/channelFaultHandler()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.messaging::Channel/connectFailed()
at mx.messaging.channels::PollingChannel/connectFailed()
at mx.messaging.channels::AMFChannel/statusHandler()

Maybe wrong context root ? Where ? To keep things as simple as possible I'm renaming testdrive.war to ROOT.war. And yes ! It works. I've added maven jetty plugin to be able to run web application directly from command line, I just love it. BTW, here is the svn diff file (patch) which you can apply as described here and don't do manual editing. It's simple, but maybe could be useful for someone.

Now I'm going to test all this stuff to see how can I benefit from using integration.

Friday, August 21, 2009

Java Champion Yakov Fain started podcast

Here is a few words about Yakov (from book "Rich Internet Applications with Adobe Flex & Java")

Yakov Fain is a Managing Principal of Farata Systems. He’s responsible for the enterprise architecture and emerging technologies. Yakov has authored several Java books, dozens of technical articles, and his blog is hugely popular. Sun Microsystems has awarded Yakov with the title Java Champion. He leads the Princeton Java Users Group. Yakov holds a BS and an MS in Applied Math and is an Adobe Certified Flex Instructor.
Link : http://nobsit.podbean.com/

Wednesday, August 19, 2009

Adobe Flex , BlazeDS and Spring data push RIA app

I'm playing with Adobe Flex 3 and BlazeDS last time. It's pretty fun! Imagine some kind of application where we need to process and visualize data which we fetching from some service at regular basis, for example every second. Maybe not so regular, maybe 10 seconds or something else. So, it's better to notify client that we have a new data and send it to client for processing. Data push - is when server pushing data to client, every time new data become available.

My example of such kind of application is RIA app for JVM free memory monitoring. It's probably useless, but approach is right, I suppose :) I have Adobe Flex 3 on client and Spring 2 + BlazeDS+Quartz on backend. I don't want to dive into technical details here(not now, sorry, maybe latter), just code and video of working application. Source is here (FlexMemoryMonitoring) and here is the video :

You can see fresh version of this application online.

Friday, May 22, 2009

My first Adobe Flex app - DZone RSS reader widget

I'm playing with Adobe Flex at this moment and want to share some impressions about Flex. To be short... Flex is definitively great ! I'm really hate Flash banners (Ablock Plus rock solid, besides) but Flex is pleasant instrument. Without any previous Flash experience I was able to create simple, but I hope interesting application - DZone RSS reader widget. It fetches RSS feed from dzone, and show items. Items are clickable, a little bit more detailed description is showed in pretty tooltip. You can list rss items, 10 per "page". There are 25 items at dzone rss, so pagination is needed. You can see it in action here.

The sad part of story is that my app doesnt works in IE 6 (or IE 7 too ?) but in FF3 all is OK. As for me it's strange... the same app, but behaviour is different. I'm getting this error message:

[RPC Fault faultString="HTTP request error" faultCode="Server.Error.Request" faultDetail="Error: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032"]. URL: http://feeds.dzone.com/dzone/frontpage"]
I have no idea why. Maybe some IE specific security manager, or something like that ? In FF3 all is OK... So, if you have some idea about resolving this issue, give me a sign, please. I hope it's something minor... If somebody become interested in this, I will share the source, it's something about 300 loc.

Source code is here

Thursday, April 16, 2009

Google XML Pages - HelloWorld app with source code

Last time I blogged was October 20, 2008... Wow ! Time is going so fast ! I'm really appreciate my readers who stayed with me and keep signing up using feedburner. You rock ! :)

So, to be closer to topic... Google XML Pages or GXP - seems to be interesting since it has been used in an army Google products - AdSense, Blogger, and Google Reader. I have some previous Apache Velocity experience, so the questions are what GXP is, what the differences between the two if any, performance ? I'll try to highlight some of this points in my next post, but for now - just hello world app.

There is a lot of information about GXP, almost all of this info - just annonce. No code, no example...
Our GXP template loooks like this :

<gxp:template name="com.google.code.projects.BlogSrc.GxpApp.HelloGxp"
gxp:ispace="preserve" gxp:espace="collapse"

<gxp:import class='java.util.List' />
<gxp:param name='list' java:type='List{Integer}' />

<gxp:loop type='Integer' var='listItem' iterable='list'>
Value : <gxp:eval expr='listItem'/>


What do we have here ? Template which takes as param List with name "list", iterates through list and print values stored in it. As you can see, template code is XML, actually. But ! After compiling this XML using GXP compiler we'll get Java source file with appropriate API for calling our template. Java method for calling template looks like this:

public static
void write(
final java.lang.Appendable gxp$out,
final com.google.gxp.base.GxpContext gxp_context,
final List<Integer> list)
throws java.io.IOException
final java.util.Locale gxp_locale = gxp_context.getLocale();
boolean gxp$bool$0 = false;
for (final Integer listItem : list) {
if (gxp$bool$0) {
gxp$out.append(" ");
} else {
gxp$bool$0 = true;
gxp$out.append("\nValue : ");
.append(gxp$out, gxp_context, (listItem));
Please notice list and listItem variables and their types. The last step is actually put some param and get result. The name of our tempale is com.google.code.projects.BlogSrc.GxpApp.HelloGxp, the name of file is HelloGxp.gxp. Result of template compilation is a java file - HelloGxp.java in package "com.google.code.projects.BlogSrc.GxpApp". Simplest way to run tempale code is just call static write() method from generated class HelloGxp. Something like this :

package com.google.code.projects.BlogSrc.GxpApp;

import com.google.gxp.base.GxpContext;
import com.google.gxp.html.HtmlClosure;
import com.google.gxp.base.GxpClosure;

import java.io.*;
import java.util.*;

public class MyHelloWorld
StringWriter out = new StringWriter();
GxpContext gxpContext =
createGxpContext(Locale.US, false);
GxpContext createGxpContext(Locale locale, boolean useXmlSyntax)
return new GxpContext(locale, useXmlSyntax);

public void testHello() throws Exception
final List<Integer> list = new ArrayList<Integer>();

HelloGxp.write(out, gxpContext,list);
public static void main(String args[])
final MyHelloWorld obj = new MyHelloWorld();
String s = obj.out.getBuffer().toString();
catch(Exception ex)
Complete source code you can find here.

GxpHelloWorldMavenBuild - the same project but for use with Maven 2.