Ramblings Of a Madman

Yeah, like i would know a good description…

Posts for Tag: tutorials

Using Dropbox to automatically download torrents

Need to be able to remotely add torrents to your secure machine at home? Don't want to expose any ports to the world in order to accomplish that?

Solution: Use Dropbox and uTorrent.

How? Setup uTorrent to automatically download any torrent files found in your Dropbox folder (like the picture says). After that, any torrent files that you put in Dropbox - from any computer where you set it up - will begin to be downloaded. Oh, the joy :)

Spring and hibernate- Lazy loading collections in desktop (swing) applications

So here's something you can't find on the internets. Or at least i couldn't, when i was trying to find a way to do this.

The problem:

Traditionally, spring and hibernate have been mostly used in web applications. In this case, you can easily define your domain objects to have lazy collections because spring/hibernate will keep an open session during the whole handling of each web request. This means that you can access lazy loading objects even in your views (provided you use the open session in view filter ;)).

Now, in desktop applications you usually don't go around having open sessions all the time which means that, unfortunately, when you try to get a lazy loading collection, hibernate will give you a big finger in the form of a LazyInitializationException due to the fact of no open sessions existing.

One solution:

My application's structure is such that no UI classes are being managed by spring (and by this i mean your mileage may vary with this solution), only my services and data access objects (DAOs) are. The UI accesses the services by use of a ServiceLocator pattern (which can be more or less complex, depending on your needs) and the DAOs in the services are autowired. The rest is just spring plumbing.

The way i found more elegant to deal with the lazy loading problem is the following. Take this bean (for the sake of simplicity some annotations or methods might be missing, beware): @Entity public class MyBean { @Column(name = "NAME") private String name;

@CollectionOfElements(fetch = FetchType.LAZY) private Set<AnotherBean> children;

public Set<AnotherBean> getChildren() { return children; } } If you try to access getChildren() hibernate will complain so i changed the method to this: public Set<AnotherBean> getChildren() {

children = DBUtils.initializeIfNeeded(this, children); return children; } And here's the definition of that static method: public static <T> Set<T> initializeIfNeeded(Object obj, Set<T> collection) {

if (!(collection instanceof PersistentCollection)) {

return Sets.newHashSet(); }

if (!((PersistentCollection) collection).wasInitialized()) {

ServiceLocator.get(CompanyDA.class).initializeLazyCollection(obj, collection); }

return collection != null ? collection : Sets.<T>newHashSet(); } What we are doing is checking whether this collection is a instance of hibernate's PersistentCollection and, if not, getting out. If it is, and hasn't been initialized, we call a special method in the super of all my DAO's that is responsible for asking hibernate to initialize the collection. Take into account that this method has to be inside a spring managed bean (i.e. non static) otherwise it won't be able to open a new session and you're back to square one.

Here's the definition of that method in the DAO: public void initializeLazyCollection(Object obj, Collection<? extends Object> collection) { sessionFactory.getCurrentSession().lock(obj, LockMode.NONE); new HibernateTemplate(sessionFactory).initialize(collection); } Hope this helps anyone and if you know of a better way to do the same thing, please share :)

Peace out.

Java Web Start (jnlp) simple example

UPDATE (2013/05/28): Since most people already know, WebStart is a bit of a crappy piece of tech with a bunch of limitations. The good news is there are alternatives :)

One of my current projects requires me to deliver a Swing application via Java Web Start. This meant some research to figure out how that works. Since i'm a nice guy, here's the result for everyone that needs it.

As you can see - in the folder structure image - there are some files that are required for the whole thing to work. Here's a brief explanation about each of them (in my creation order ;)):

src/org/Test.java : My source code. It's just a simple main that creates a JFrame and displays it; Manifest.txt : The manifest file used to create the jar file that gets served by Java Web Start; faren.jar : My application's jar. I'll explain how to create it in a while; faren.jnlp : The Java Web Start description file; faren.html : The html file that contains the button to start the application.

The first thing we want to do is create the source file. In the case of my simple test, here are its contents (blank lines removed for brevity): Test.java package org;

import javax.swing.JFrame; import java.awt.Dimension;

public class Test {   public Test() {     JFrame faren = new JFrame("Test");     faren.setSize(new Dimension(300, 300));     faren.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     faren.setVisible(true);   }   public static void main(String[] args) {     new Test();   } } Moving on to the jar manifest file, it basically just says what the main class will be: Manifest.txt Main-Class: org.Test Creating the jar is as simple as running the following command: jar cfm faren.jar Manifest.txt org It creates the faren.jar file, using the manifest file and the sources contained within the org folder. If - like me - you use Maven, you will have this for free using the app-assembler plugin, but for the test's purposes i didn't want to create a full maven project :)

Now we need to define a description file for the Java Web Start mechanism: faren.jnlp <?xml version="1.0" encoding="UTF-8"?> <jnlp spec="1.0+" codebase="file:///Users/pedroassuncao/Desktop/jnlp_example">   <information>     <title>Dynamic Tree Demo</title>     <vendor>Dynamic Team</vendor>   </information>   <resources>     <!-- Application Resources -->     <j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>     <jar href="faren.jar" main="true" />   </resources>   <application-desc     name="Dynamic Tree Demo Application"     main-class="org.Test"     width="300"     height="300">   </application-desc>   <update check="background"/> </jnlp> Just to explain a little bit of what is going on in here (the important parts), what you want to make sure is that the codebase property is set correctly to the absolute path where the html file will be served from (in the case of a final deployment this will be something like http://myserver/jnlp/myapp, but in this case i'm serving without a web server, hence the file:/// part). You will also want to define a minimum version for the virtual machine of the client (the 1.6+ part) and eventually extend this information with the <shortcut> tag, that allows you to ask web start to create a desktop icon for your application on the clients' computers. A full description of the structure of this file can be found here.

Finally, we need an html file that will show the java web start button. The following will suffice for now: faren.html <html>   <head></head>   <body>     <script src="http://www.java.com/js/deployJava.js"></script>     <script>       // using JavaScript to get location of JNLP file relative to HTML page       var dir = location.href.substring(0, location.href.lastIndexOf('/')+1);       var url = dir + "faren.jnlp";       deployJava.createWebStartLaunchButton(url, '1.6.0');     </script>     <noscript>       <a href="faren.jnlp">Launch</a>     </noscript>   </body> </html> If the client's browser supports javascript, this will use a special script from the java website that will ask to install the virtual machine if the client does not have it (or upgrade an existing one). If he doesn't support javascript it will just show a link that will try to launch the java web start (depending a lot on whether the user's file associations are correct (i.e. .jnlp files being assigned to the java executable).

Finally, with all this in place, point your browser to the place where you have the faren.html file and click the button; the application should launch.

By the way, does anyone know why my desktop shortcut is not being added on OSX? :)

Sproutcore on OSX snow leopard

It recently came to my attention the existence of this heavily-client-based web framework to develop desktop-like applications called Sproutcore and is backed up by Apple (there is another cool alternative called Capuccino). Basically it relies on Javascript to create nice desktop-like applications, but on the web.

Ever since i heard about node.js i have been curious to try out one of these things. My ideas on it will come later but, for now, here are the required steps to make Sproutcore work well on OSX snow leopard. And i say work well because if you rely on the vanilla Ruby 1.8.7 that comes with snow leopard you will have a very crappy experience with Sproutcore; It will take approximately 35 seconds to reload any webpage every time you make a code change. And that will make you not want to use it at all.

Fortunately a lot of people have been kind enough to explain me, on twitter, how to make it faster.

But let's start from the beginning:

1. Install Sproutcore using GEM, like so: sudo gem install sproutcore Note: I don't remember if gem comes installed with snow leopard. If not, you can always google it :)2. Follow the rest of the steps to setup your first application

By now you should have realized that (if you are using OSX snow leopard) the damn thing is freaking slow. So...

3. ...download and compile the Ruby 1.9 source code for OSX tar xzvf ruby-1.9.1-p376.tar.gz cd ruby-1.9.1-p376 ./configure --enable-shared --enable-pthread CFLAGS=-D_XOPEN_SOURCE=1 make sudo make install Note: The actual version could be different, as stuff evolves over time ;)4. Update the symbolic link on your system to point to the new ruby installation sudo rm /usr/bin/ruby sudo ln -s /usr/local/bin/ruby /usr/bin/ruby 5. Make sure the correct Ruby version is in use ruby --version Should return something like this: ruby 1.9.1p376 (2009-12-07 revision 26041) [i386-darwin10.3.0] 6. Install thin. This server is faster than the one that comes with Sproutcore sudo gem install thin 7. All done. Give it a try again

If you try to refresh the page of a Sproutcore example now you will notice the speed difference, like night to day. Have fun coding client-side desktop web applications :)

I'm planning to also take a look at Capuccino, another similar framework, but created in Objective-J - a derivative of Objective-C for javascript. Looks interesting and it might get me into iPhone development at last :)

Websockets tutorial/example with pywebsocket

As everyone already knows, Google Chrome now supports websockets. In essence, this allows you to keep a connection open with a webserver indefinitely (analogous to typical sockets) and send data bi-directionally. Unfortunately Chrome is the only browser currently supporting this, but I'm pretty sure this will change.

So I decided to give this a try and experiment a bit with it. This is my step by step process on getting a web page opening a websocket to a server and receiving the server's date and time every second. It is based on an article by Joe Armstrong, though he uses Erlang for the server, while I decided to follow the easy road and use Google's pywebsocket - an apache module (uses mod_python) that allows you to create handlers for websocket connections in a easy-to-use fashion. The code also contains a way to start a standalone server (i.e. not requiring apache) for testing purposes.

So here are the steps I took to get this working: 1. Create a web page This is the code I borrowed from Joe, though slightly modified to fit my purposes (it requires jquery, by the way): <html>


<script src="jquery-1.3.2.min.js"></script> <script>


var ws;

if ("WebSocket" in window) { debug("Horray you have web sockets. Trying to connect..."); ws = new WebSocket("ws://localhost:9998/echo");

ws.onopen = function() { // Web Socket is connected. You can send data by send() method. debug("connected..."); ws.send("hello from the browser"); ws.send("more from browser"); };

run = function() { var val=$("#i1").val(); // read the entry $("#i1").val("");       // and clear it ws.send(val);           // tell erlang return true;            // must do this };

ws.onmessage = function (evt) { //alert(evt.data); var data = evt.data; var i = data.indexOf("!"); var tag = data.slice(0,i); var val = data.slice(i+1); $("#" + tag).html(val); };

ws.onclose = function() { debug(" socket closed"); }; } else { alert("You have no web sockets"); };

function debug(str){ $("#debug").append("<p>" +  str); };

}); </script>



<h1>Interaction experiment</h1>

<h2>Debug</h2> <div id="debug"></div>

<fieldset> <legend>Clock</legend> <div id="clock">I am a clock</div> </fieldset>


</html> 2. Download and install pywebsocket Checkout the code with svn checkout http://pywebsocket.googlecode.com/svn/trunk/ pywebsocket-read-only

Then do python setup.py build and sudo python setup.py install inside the src folder. This will install it into your python environment. 3. Being lazy, means we will change an example handler The way pywebsocket works is delegating the connections to something they call handlers. In the pywebsocket-read-only/src/example folder you will find a file named echo_wsh.py. They have this convention where handlers are named <entry_point>_wsh.py. This means that when you later call (from your web page) the url http://localhost:9998/echo the server will delegate the processing of that connection to that file.

I modified that file to something like this: # Copyright 2009, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # #     * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. #     * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. #     * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from mod_pywebsocket import msgutil from datetime import datetime import time


def web_socket_do_extra_handshake(request): print 'Connected.' pass  # Always accept.

def web_socket_transfer_data(request): while True: time.sleep(1) date = datetime.now() #try: #    line = msgutil.receive_message(request) #except Exception, e: #    print 'Foi com os porcos' #    raise e #print 'Got something: %s' % line #msgutil.send_message(request, line) msgutil.send_message(request, 'clock!%s' % date) #if line == _GOODBYE_MESSAGE: #    return So basically whenever a new connection is made to this entry point, a call to web_socket_do_extra_handshake is made. After that, web_socket_transfer_data is called and it's your responsibility to create the loop that receives messages and handles the flow (as you can see in the commented lines). I don't care about that right now, since I only want to push the date and time to the client every second. 3. Start the standalone server Go to the pywebsocket-read-only/src/mod_pywebsocket folder and run the following command: sudo python standalone.py -p 9998 -w ../example/ This will start the server in port 9998 and use the handlers directory specified by the -w option. That is where our echo_wsh.py lives. 4. Test it :D So now open your browser (remember, only chrome supports websockets currently) and open the html file your created in the beginning. Voilá, server's date and time every second in the clock div.