JacORB on Linux and Mac OSX

We have seen many Classmates having trouble to get JacORB running on Linux and Mac OSX, so here is a step-by-step installation tutorial:

Change to the directory where JacORB should be located:
cd ~/src/

Move the provided zip file to the location (or get jacorb via wget):
mv ~/Downloads/SW8-Komponentenarchitektur.zip .

Unzip the file:
unzip SW8-Komponentenarchitektur.zip

Rename the folder to something reasonable:
mv SW8-Komponentenarchitektur jacorb

Change to the directory:
cd jacorb
Unzip the jacorb source:
unzip jacorb-2.3.1-src.zip

Rename the new folder to something reasonable. I use the Version as folder name, so i can have multiple versions in this directory:
mv jacorb-2.3.1-src 2.3.1

Edit the Properties File and fill in the current Paths:
vi jacorb.properties

jacorb.home=/Users/gasserp/src/jacorb/2.3.1
java.endorsed.dirs=/Users/gasserp/src/jacorb/2.3.1/lib
jacorb.naming.ior_filename=/Users/gasserp/src/jacorb/2.3.1/lib/NS_Ref
ORBInitRef.InterfaceRepository=file:/Users/gasserp/src/jacorb/2.3.1/lib/IR_Ref

Move the Properties file to the correct location:
mv jacorb.properties 2.3.1/etc/

Build the Code:
cd 2.3.1
ant clean
ant

Move up one directory:
cd ..

Remove unused Files:
rm apache-ant-1.7.0-bin.zip
rm jacorb-2.3.1-src.zip
rm set_env.cmd
rm start_ns.cmd

Set you Path for the NS binary:
export PATH=$PATH:/Users/gasserp/src/jacorb/2.3.1/bin/

Start the NS Service:
ns -DOAPort=38693

Remember: The Path you set via export is only valid in the actual Shell. If you want to set your PATH permanently, add the following line in your ~/.bashrc or ~/bash_profile:
PATH=$PATH:/Users/gasserp/src/jacorb/2.3.1/bin/
export PATH

Your done!

Sind Zürichs Dönerläden rassistisch?

3 Uhr morgens in Zürich. Die Party ist vorbei und etwas Energie tanken würde nicht schaden.

Also gehe ich in einen Dönerladen. Doch statt dem Gebratenen Reis (Nasi Goreng) gibts einen Gebratenen Nazi :) Aber seht doch am besten selbst.

Nazi Goreng

2011-04-25 | Posted in: Fun | Comments Closed

Höhenflug mit Delta-Modellflieger über der HSLU T&A

Was macht man mit einem iPod mit eingebauter Kamera, einem Swift 2 Delta-Modellflieger, einem total überdimensioniertem Motor und einem Dach auf ca. 25m Höhe?

Richtig, man füge all diese Komponenten zusammen und schlussendlich entsteht ein Film in atemberaubender Höhe über Horw.

YouTube Preview Image

PS: Leider war die Kamera zu nahe am Motorenregler angebracht, darum die lästigen Wellenmuster im Film. Beim nächsten Mal kommts sicher besser, versprochen ;)

Hier noch ein kurzes Video von einem schnellen Takeoff vom Boden aus. Der Motor würde noch einiges mehr leisten, es wäre auch möglich direkt senkrecht zu starten :-D

YouTube Preview Image
2011-04-22 | Posted in: Fliegen | Comments Closed

Im Zweifelsfall für den Angeklagten

Wenn ein Student alte Prüfungen online stellt, dann gefällt das nicht allen Dozenten. Mir auch nicht. Ich möchte ja nicht dauernd neue Prüfung schreiben. Unbestreitbar ist aber der Lerneffekt. Ich habe immer am besten gelernt wenn ich alte Prüfungen durchgearbeitet habe. Ich erinnere mich an meinen Physik Dozenten. Er war schon ein erfahrener alter Hase. Prüfungsvorbereitung? “Hier haben sie eine Auswahl an vergangenen Prüfungen”, und drückte mir einen ganzen Stapel alter Prüfungen in die Hand. Nach der sechsten konnte ich den Stoff perfekt und wurde auch mit einer guten Note belohnt.

Wo liegt der Unterschied zwischen einen Stapel voll alter Prüfungen austeilen (die ja schlussendlich auch Kopiert werden konnten) und einer Publizierung Online? Aus meiner Sicht keiner (Ursula bitte korrigiere mich) – Falls die Rechte und Wünsche der Urheber respektiert werden. Wer ist nun Urheber (resp. der Besitzer der Rechte)? Ist das der Dozent oder der Arbeitgeber? Ich möchte mich dazu nicht äussern aber ich denke der Fall ist auch ohne Jurastudium klar. Nun zum zweiten Aspekt “Wünsche”. Der Wunsch einer jeden Hochschule ist das gute abschneiden der Studierenden. Wir tun alles dafür dass unsere Studierenden den Stoff gut begreifen und als gute Ingenieure ins Berufsleben entlassen werden. Wir besuchen Didaktische Weiterbildungen, nehmen regelmässig an Workshops teil die uns den vermitteln wie wir den Unterricht und die Prüfungen besser und gerechter durchführen können. Alles zum Guten für die Studierenden. Wie ist es nun mit den online gestellten Prüfungen? Wird da der Studierende zuerst mal verdächtigt er missbrauche diese Prüfungen? Oder gibt es andere Gründe dies zu verbieten? Ich weiss es nicht. Ich weiss nur dass der Absicht sicher kein schlechter Gedanke zugrunde liegt. Eigentlich ist das Engagement lobenswert. Vielleicht sollte man einfach durch das Gespräch einen Konsens suchen. Eine mögliche Lösung wäre dass es ein Login braucht dass nur Members von der Hochschule diese Webseiten besuchen können (AAI).

Lieber Student, ich denke sie sind durch ihr Engagement eine Bereicherung für unsere Schule. Sie erinnern mich wie wir alle einmal waren. Voller Ideen und Tatendrang, manchmal auch ungestüm über das Ziel hinausschiessend. Ich bin sicher sie werden das Problem durch Gespräche mit dem Dozenten lösen. Ich hoffe in ihrem Sinne.

OpenId in a Web Application based on Java EE and JSF 2.0

This is an example how to connect your JSF 2.0 Website with an OpenId Provider by using the openid4java-library. It exists already some examples/tutorials for JSPs (see [1],[2] and [3]), but I found none based on JSF. So I decide to write my own. The followings are based on the examples above and the Seam OpenId implementation (see org.jboss.seams.security.openid).

First, add the openid4java library to the web applications class path. You find an installation description here.

Second step is to create two pages. One to fire up the login procedure and one to process the response. I called them index.xhtml (startpage) and openid.xhtml (redirectpage). The index.xhtml is quite simple. It looks like this:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <h:outputLabel for="openid">Open ID</h:outputLabel>
            <h:inputText id="openid_identifier" value="#{openid.userSuppliedId}"
                      style="background: url(http://openid.net/login-bg.gif) no-repeat; padding-left: 18px; background-position: 0 50%;" />
            <h:commandButton action="#{openid.login}" value="Login" id="openid"/>
        </h:form>
    </h:body>
</html>

To improve the user recognition, I styled the h:inputtext with the openid logo (see the style attribute “style=“).

The other page, the openid.xhtml presents the response from the openid provider and looks like:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <h:inputHidden value="#{openid.onLoad}"/>
 
            <h:outputLabel for="userSuppliedId" value="User Supplied Id: "/>
            <h:outputText id="userSuppliedId" value="#{openid.userSuppliedId}"/>
            <br/>
            <h:outputLabel for="fullname" value="Fullname: "/>
            <h:outputText id="fullname" value="#{openid.openIdFullName}"/>
            <br/>
            <h:outputLabel for="firstname" value="Firstname: "/>
            <h:outputText id="firstname" value="#{openid.openIdFirstName}"/>
            <br/>
            <h:outputLabel for="lastname" value="Lastname: "/>
            <h:outputText id="lastname" value="#{openid.openIdLastName}"/>
            <br/>
            <h:outputLabel for="country" value="Country: "/>
            <h:outputText id="country" value="#{openid.openIdCountry}"/>
            <!-- go on... --->
        </h:form>
    </h:body>
</html>

You may be notice the inputHidden field? Because of there is no page init method (like onLoad) in JSF, I create a hidden input-field, which shows (invisible) a dummy member. In the getter method of the member, I execute my init routine ;-) . More about that later…

So let’s talk about the key element – my Session Bean. Some code fragments are copied from the seam openid implementation. Explanations are in and below the source code.

/*
 * Created tdmarti, HSLU T&amp;A - D3S (2011)
 */
package ch.hslu.d3s;
 
import java.io.IOException;
/** ... */
import org.openid4java.message.ax.FetchResponse;
 
/**
 * Authenticate the user against a openid provider
 * @author tdmarti
 */
@Named("openid")
@SessionScoped
public class OpenId implements java.io.Serializable {
 
    /** Creates a new instance of OpenId */
    public OpenId() {
    }
 
    private String userSuppliedId; //Users OpenID URL
    private String validatedId;
    private String openIdEmail;
    /* ... */
    private String onLoad;
    private ConsumerManager manager;
    private DiscoveryInformation discovered;
 
    public void login() throws IOException {
        try {
            manager = new ConsumerManager();
        } catch (ConsumerException e) {
            System.out.println("Error creating ConsumerManager.");
        }
        validatedId = null;
        String returnToUrl = returnToUrl("/openid.xhtml");
        String url = authRequest(returnToUrl);
 
        if (url != null) {
            FacesContext.getCurrentInstance().getExternalContext().redirect(url);
        }
    }
 
    /**
     * Create the current url and add another url path fragment on it.
     * Obtain from the current context the url and add another url path fragment at
     * the end
     * @param urlExtension f.e. /nextside.xhtml
     * @return the hole url including the new fragment
     */
    private String returnToUrl(String urlExtension) {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        String returnToUrl = "http://" + request.getServerName() + ":" + request.getServerPort()
                + context.getApplication().getViewHandler().getActionURL(context, urlExtension);
        return returnToUrl;
    }
 
    /**
     * Create an authentication request.
     * It performs a discovery on the user-supplied identifier. Attempt it to 
     * associate with the OpenID provider and retrieve one service endpoint 
     * for authentication. It adds some attributes for exchange on the AuthRequest.
     * A List of all possible attributes can be found on @see http://www.axschema.org/types/
     * @param returnToUrl
     * @return the URL where the message should be sent
     * @throws IOException
     */
    private String authRequest(String returnToUrl) throws IOException {
        try {
            List discoveries = manager.discover(userSuppliedId);
            discovered = manager.associate(discoveries);
            AuthRequest authReq = manager.authenticate(discovered, returnToUrl);
 
            FetchRequest fetch = FetchRequest.createFetchRequest();
            fetch.addAttribute("email",
                "http://schema.openid.net/contact/email", true);
            /* Some other attributes ... */
 
            authReq.addExtension(fetch);
            return authReq.getDestinationUrl(true);
        } catch (OpenIDException e) {
            // TODO
        }
        return null;
    }
 
    public void verify() {
        ExternalContext context = javax.faces.context.FacesContext
                .getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest) context.getRequest();
        validatedId = verifyResponse(request);
    }
 
    /**
     * Set the class members with date from the authentication response.
     * Extract the parameters from the authentication response (which comes
     * in as a HTTP request from the OpenID provider). Verify the response,
     * examine the verification result and extract the verified identifier.
     * @param httpReq httpRequest
     * @return users identifier.
     */
    private String verifyResponse(HttpServletRequest httpReq) {
        try {
            ParameterList response =
                    new ParameterList(httpReq.getParameterMap());
 
            StringBuffer receivingURL = httpReq.getRequestURL();
            String queryString = httpReq.getQueryString();
            if (queryString != null &amp;&amp; queryString.length() &gt; 0) {
                receivingURL.append("?").append(httpReq.getQueryString());
            }
 
            VerificationResult verification = manager.verify(
                    receivingURL.toString(),
                    response, discovered);
 
            Identifier verified = verification.getVerifiedId();
            if (verified != null) {
                AuthSuccess authSuccess =
                        (AuthSuccess) verification.getAuthResponse();
 
                if (authSuccess.hasExtension(AxMessage.OPENID_NS_AX)) {
                    FetchResponse fetchResp = (FetchResponse) authSuccess.getExtension(AxMessage.OPENID_NS_AX);
 
                    List emails = fetchResp.getAttributeValues("email");
                    openIdEmail = (String) emails.get(0);
                     /* Some other attributes ... */
                }
                return verified.getIdentifier();
            }
        } catch (OpenIDException e) {
            // TODO
        }
        return null;
    }
 
    /**
     * hidden member for onLoad/Init event. 
     *@return always return the string pageLoaded
     */
    public String getOnLoad() {
        verify();
        return "pageLoaded";
    }
 
    /**
     * Getter and Setter Method
     */
    public String getUserSuppliedId() {
        return userSuppliedId;
    }
    public void setUserSuppliedId(String userSuppliedId) {
        this.userSuppliedId = userSuppliedId;
    }
    public String getValidatedId() {
        return validatedId;
    }
    public String getOpenIdEmail() {
        return openIdEmail;
    }
/* Other getters ... */
}

After you deploy and start them you will see a page like this
JSF Page with OpenID Login
Now the user can identify itself by filling in his OpenId URL like http://<<username>>.myopenid.com or https://www.google.com/accounts/o8/id (google is also an OpenId provider, type the google URL and you will redirected to the google login page).

Explanation

I try to explain the most things in the javadoc – read it first.

Add new/other Attributes

FetchRequest fetch = FetchRequest.createFetchRequest();
fetch.addAttribute("email", "http://schema.openid.net/contact/email", true);

You can add others/more attributes on the request. You will find a list here. But be carefully not each OpenId Provider support the current valid specification. For example myopenid want the attribute http://schema.openid.net/contact/email or http://schema.openid.net/namePerson and not http://axschema.org/contact/email and http://axschema.org/namePerson.
My workaround is a if-then switch like (I omit it on the example above)

if (userSuppliedId.contains("myopenid")){
  fetch.addAttribute("email", "http://schema.openid.net/contact/email", true);
  fetch.addAttribute("fullname", "http://schema.openid.net/namePerson", true);
/* ... */
} else {
  fetch.addAttribute("email", "http://axschema.org/contact/email", true);
  fetch.addAttribute("fullname", "http://axschema.org/namePerson", true);
/* ... */

May be I post a bit later a list of different attributes, which I have found.

Fetch the answer

Be careful, the getAttributeValue parameter has to match to the first parameter on the addAttributemethod (case sentitiv).

List emails = fetchResp.getAttributeValues("email");
openIdEmail = (String) emails.get(0);
/* or also possible */
openIdEmail = fetchResp.getAttributeValue("email");

onLoad

As I already wrote, JSF has not a on Load or Init method, which is called very time a page is loaded. My workaround is to create a class member which is displayed in a hidden field on the page. Because of the sequentially execution, the hidden field should be placed on the top of the page and you get your onLoad event ;-) .

public String getOnLoad() {
  verify(); //should call, when the page is loaded
  return "pageLoaded";
}