Friday, December 24, 2010

Multiple File Upload Options

I was recently confronted with a question about how to do multiple file uploads from a browser based application. The HTML 4.x specification is pretty open on the file upload requirements, and all of the browser implementations are very basic.  Firefox, Safari, Web Toolkit, and Internet Explorer all provide a method to upload one file at a time, but no multiple file upload. As a result, clever coders have come up with a number of solutions. Here are a few.

These are some approaches available to you. If you are using a JSF based framework, a number of them already include a multiple file upload component based on Apache Commons File Upload.

Wednesday, December 08, 2010

Apache HTTPClient 4.x Preemptive Authentication

I am using the Apache HttpClient for some work I am doing at the office. It is a really cool utility to perform web based work. A common requirement of such work is to use authentication.

The default behavior of the HttpClient is to try and connect to the resource and read the response. If the response is a 401 Unauthorized, the client sends the request again using the credentials that are set in the client. This results in an unnecessary double posting of the request. It is however compliant with RFC2616 Section 10.4.2 which describes this behavior.

In the previous version of the client (3.x), you could set the preemptive authentication with the code below:

httpClient.getParams().setAuthenticationPreemptive(true);

However, version 4.x does not support this convenient arrangement. There is a more flexible arrangement using interceptors. The client supports interceptors on both the request, and the response. The use of interceptors makes the code a little more complex, but the flexibility of using multiple interceptors, and ordering them makes up for the additional code required.

I can not provide an example of my code since it was something I created for work, but here are two examples. The first is complete, and the second is simply an example.


There is an additional post on stackoverflow which indicates you may be able to use a simple addition to the header. This may work for simple clients, but it is not as flexible as the interceptor form. I have not tested the code, but have included Adam Batkin's code snippet below.

String username = ...
String password = ...
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);

HttpRequest request = ...
request.addHeader(new BasicScheme().authenticate(creds, request));

Enhanced by Zemanta

Apache Commons IO 2.0

Congrats to the Apache Commons IO Team on the release of the 2.0 framework. It has been a long time coming. The latest libraries require Java 1.5 which is a quantum jump in Apache terms. The old library required Java 1.3.

The IOUtils class provides a number of convenience methods to handle most IO operations. One of my favorite methods is IOUtils.copy(InputStream input, OutputStream output). A simple method, but so very useful since it is so common.

Have you ever needed to create unit tests on methods which require a closed InputStream, or OutputStream. I am sure you have, if not you just have not gotten there yet. Apache Commons IO offers you ClosedInputStream and ClosedOutputStream.

There are some other nice classes especially for debugging like CountingInputStream and CountingOutputStream which records the number of bytes read, or written. I can see another use for cloud computing models where you are charged for data transfers. This can help you keep track of those numbers for comparison with your charges.

If you have not taken the time to look at these great tools, take a couple of minutes to just look at the javadocs. I am sure you will be impressed like me.
Enhanced by Zemanta

Saturday, November 27, 2010

Dynamic JSF 2.0 Page

I have had a number of folks ask about templates and JSF. There seems to be a misconception that you need a template for all of your content, and that the content can not be dynamically generated for a page. This is not true! I am not sure where this comes from, but it is not uncommon question.

Dynamic JSF Page

The example NetBeans project in the link below, demonstrates how to to use the binding attribute to inject the required information into a page before rendering it. I have added the binding attribute to the <body> tag. This allows me to modify the content of the page body before it is rendered.

I have also included how to use the ValueExpression to set the value of the rendered text. This example should be sufficient to demonstrate the capabilities.

The project code is a NetBeans project: DynamicJSF.zip
Enhanced by Zemanta

Thursday, November 25, 2010

Oracle Certified Java Programmer Boot Camp Code Examples

Java Mascot introducing Netbeans.Image via Wikipedia
I uploaded all of my code examples today for the free Oracle™ Certified Java™ Programmer Boot Camp that I do for the Greenville Java Users Group (GreenJUG).

You can find more information on the JUG site about the boot camp, and from the links below. The projects are NetBeans 6 files.

You need to still need to attend for the presentations! If I posted those, you wouldn't feel the need to come and participate.

Code Examples

Links



Enhanced by Zemanta

Wednesday, November 24, 2010

Creating Charts on Headless Systems: JFreechart and Rogue Wave

JFreechart Example
This week we had an interesting conundrum at work. We had a headless server which is not uncommon, that would not generate charts in our web based application. Apparently some of the charts are not used very often, or it would have been reported sooner. The charts in question were originally created using Rogue Wave Software charting software from 1999-2000. This software was used to create charts in AWT based applications. Yes, I said AWT not Swing, and I know that it is very old.

The particular charts do not have replacements available in free charting software like JFreechart currently, and are available only as commercial software. We had purchased the original software and licenses from Rogue Wave, and did not want to purchase new commercial software.

Now to the conundrum. Since Java 1.4, heavyweight AWT and Swing components throw a HeadlessException, if you attempt to run them on a headless system.

As you can see from the list, it does not leave much room for the developer to work with in a headless environment. Fair enough, AWT/Swing are GUI environments.

The graphical libraries used to create charts in the case of Rogue Wave and JFreechart generally expect a GUI framework. Rogue Wave is expecting to generate the chart images in a Window, or one of its subclasses like Frame. This can cause an issue as you can see. So I am left with a couple of components that I can use like Component, Canvas, and Panel.

You can create a headless environment and check it with the code below.

System.setProperty("java.awt.headless", "true");
boolean headless = GraphicsEnvironment.isHeadless();
System.out.println("Headless: " + headless);

So how do you generate the charts, or create images in general on a headless system. It turns out to be quite simple. Since all components have a paint(Graphics g) method, and JFreechart has a createBufferedImage() method. These turn out to be the keys.

Solution

We need to create a BufferedImage which we can pass to the Component to paint. Once we create the image to paint to, we simply ask the component to paint it, and use ImageIO to output our chart.

Note: You will need to have the Rogue Wave graphing and gif libraries, or you may comment out those code sections.

NetBeans 6.9 project files: HeadlessAWT.zip

Headless.java

/*
 *  Copyright 2010 Blue Lotus Software.
 *  Copyright 2010 John Yeary.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package com.bluelotussoftware.graph.headless.example;

import java.awt.*;
import java.io.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.Locale;
import com.roguewave.chart.awt.datamodels.v2_2.SampleData;
import com.roguewave.chart.awt.standard.v2_2.beans.PieChart;
import com.roguewave.chart.awt.standard.v2_2.beans.LineChart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.encoders.ImageFormat;
import org.jfree.data.general.DefaultKeyedValuesDataset;
import org.jfree.data.general.DefaultPieDataset;

/**
 *
 * @author John Yeary
 * @version 1.0
 */
public class Headless {

    private static BufferedImage generateRectangle(Component component, int width, int height) {
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = bufferedImage.getGraphics();
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, width, height);
        graphics.setColor(Color.ORANGE);
        graphics.fill3DRect(50, 50, 300, 300, true);
        component.paint(graphics);
        return bufferedImage;
    }

    private static BufferedImage generateRectangle(Component component) {
        return generateRectangle(component, 400, 400);
    }

    private static BufferedImage generateCylinder(int width, int height) {
        Panel panel = new Panel();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = image.getGraphics();
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, width, height);
        graphics.setColor(Color.ORANGE);
        graphics.drawOval(100, 100, 50, 75);
        graphics.fillOval(200, 100, 50, 75);
        graphics.drawLine(125, 100, 225, 100);
        graphics.drawLine(125, 175, 225, 175);
        panel.paint(graphics);
        return image;
    }

    private static boolean save(BufferedImage image, Component component) {
        boolean success = false;
        try {
            ImageIO.write(image, "gif", new FileOutputStream(component.getClass().getSimpleName() + ".gif"));
            success = true;
        } catch (FileNotFoundException fnfe) {
            fnfe.printStackTrace(System.err);
        } catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
        return success;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        System.setProperty("java.awt.headless", "true");
        boolean headless = GraphicsEnvironment.isHeadless();
        System.out.println("Headless: " + headless);
        Toolkit tk = Toolkit.getDefaultToolkit();
        tk.beep();

        BufferedImage bufferedImage = null;
        boolean success = false;

        // ---------------------------------------------------------------------------------------------- //
        Component component = new Component() {

            private static final long serialVersionUID = 3109256773218160485L;
        };
        Canvas canvas = new Canvas();
        Panel panel = new Panel();
        // ---------------------------------------------------------------------------------------------- //

        // Drawing Examples
        bufferedImage = Headless.generateRectangle(component);
        success = Headless.save(bufferedImage, component);
        System.out.println("Created " + component.getClass().getSimpleName() + " : " + success);
        success = false;

        bufferedImage = Headless.generateRectangle(canvas);
        success = Headless.save(bufferedImage, canvas);
        System.out.println("Created " + canvas.getClass().getSimpleName() + " : " + success);
        success = false;

//        bufferedImage = Headless.generateRectangle(panel);
//        success = Headless.save(bufferedImage, panel);
//        System.out.println("Created " + panel.getClass().getSimpleName() + " : " + success);
//        success = false;

        bufferedImage = Headless.generateCylinder(400, 400);
        success = Headless.save(bufferedImage, panel);
        System.out.println("Created " + panel.getClass().getSimpleName() + " : " + success);
        success = false;
        // ---------------------------------------------------------------------------------------------- //

        // Rogue Wave Examples
        SampleData sd = new SampleData();
        LineChart lineChart = new LineChart();
        lineChart.setData(sd);
        PieChart pieChart = new PieChart();
        pieChart.setData(sd);

        // The chart size is required.
        lineChart.setSize(400, 400);
        pieChart.setSize(400, 400);

        bufferedImage = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
        lineChart.paint(g);
        ImageIO.write(bufferedImage, ImageFormat.PNG, new FileOutputStream("LineChart.png"));
        pieChart.paint(g);
        ImageIO.write(bufferedImage, ImageFormat.PNG, new FileOutputStream("PieChart.png"));
        // ---------------------------------------------------------------------------------------------- //

        // JFreechart Examples
        DefaultPieDataset dpds = new DefaultKeyedValuesDataset();
        dpds.setValue("Java", 60.0);
        dpds.setValue("C++", 20.0);
        dpds.setValue("MS Technologies", 10.0);
        dpds.setValue("Misc.", 10.0);

        JFreeChart jfc = ChartFactory.createPieChart("Programming Languages", dpds, true, true, Locale.ENGLISH);
        bufferedImage = jfc.createBufferedImage(400, 400);
        ImageIO.write(bufferedImage, "gif", new FileOutputStream("jfc-piechart.gif"));
    }
}

Enhanced by Zemanta

Saturday, November 06, 2010

JDK 7: The wait is over in OpenJDK

I did a presentation last month for our Greenville Java Users Group about the proposed features set for JDK 7. My claim is that they are already here in OpenJDK. Granted there still needs to be some fine tuning, but all of the proposed features will work.
You may need to turn on some JVM parameters to make them work, but they work.


JSR 292: Support for dynamically-typed languages (InvokeDynamic)

The following parameters need to be passed to the JVM:

-XX:+UnlockExperimentalVMOptions \
-XX:+EnableInvokeDynamic


An example of how this is implemented can be found at:

Support for Dynamically Typed Languages in the Java Virtual Machine

JSR TBD: Small language enhancements (Project Coin)

The simplified enhancements to improve developer productivity include:
  • Underscore separators for integral literals (primitive types).
  • "Diamond Operator" for simplified generic instance creation.
  • Strings in switch statements.

JSR 166y: Concurrency and Collections Updates

The best known reference is to ForkJoin operations from JavaOne, but it includes so much more. A great example of a Fork-Join operation can be found at: JSR-166: The Java fork/join Framework.

JSR 203: More new I/O APIs for the Java platform (NIO.2)

In the example at the bottom of the blog, I show the Path class. This includes some additional functionality where we expect "Files" and "Directories (path)" information to be separate.

A really cool new feature is the WatcherService API. This allows us to watch a file, or directory for changes. A great example can be found here: WatchDir.java.

This is just a few examples of the great things that are available in OpenJDK today. So if you want to try out the new features, download a binary distribution for your platform, or better still: download the source and build it yourself.

As promised here is my example code which demonstrates some of the features. You will need to download the ParallelMergeSort from the Fork-Join framework link above to compile it. Also if you are using NetBeans, it has a number of hooks already in place for OpenJDK (JDK 7/8).

Example.java

/*
 *  Copyright 2010 Blue Lotus Software, LLC.
 *  Copyright 2010 John Yeary <jyeary@bluelotussoftware.com>.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
/*
 * $Id: Example.java 304 2010-11-06 16:32:05Z jyeary $
 */
package com.bluelotussoftware.example.jdk7;

import java.io.File;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Arrays;

public class Example {

    public static void main(String... args) {

        Map<String, String> map = new HashMap<>();
        map.put("Hello", "World");
        System.out.println(map.get("Hello"));

        Map<String, Map<String, String>> multimap = new HashMap<>();
        Map<String, String> enclosed = new HashMap<>();
        enclosed.put("name", "value");
        multimap.put("map1", map);
        multimap.put("map2", enclosed);

        System.out.println(multimap.get("map2").get("name"));


        int x = 0b0_1;
        int y = 0b1000_0100_0010_0001;
        int z = 123___456___789___0;

        System.out.println(x);
        System.out.println(y);
        System.out.println(z);

        String testCase = "openJDK";

        switch (testCase) {
            case "yummy": {
                System.out.println("Yummy");
                break;
            }
            case "meloncholy": {
                System.out.println("Sad");
                break;
            }
            case "openJDK": {
                System.out.print("The future of Java...");
            }
            case "jdk7":
                System.out.print(" today.\n");
        }

        File f = new File(System.getProperty("user.home"));
        Path p = f.toPath();
        System.out.println("Current Path: " + p.toString());

        Integer[] assorted = new Integer[5000];
        Random generator = new Random();

        for (int i = 0; i < 5000; i++) {
            assorted[i] = generator.nextInt(1_000_000);
        }
        System.out.println("\n\n\n\n\nunsorted: " + Arrays.toString(assorted) + "\n\n\n\n\n");

        ParallelMergeSort.sort(assorted);

        System.out.println("sorted: " + Arrays.toString(assorted));

    }
}
Enhanced by Zemanta

Apache Maven AntRun Plugin Configuration

Apache Maven logo.Image via Wikipedia
I was looking for an up-to-date example of how to use the Apache Maven AntRun plugin version 1.6. The examples that I found on the plugin's home page have not kept pace with the actual development.

I have included my build.xml example file below, and the pom.xml configuration to run it. Please note the comments under the antrun plugin to understand what is happening.

build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="mavenproject1" default="default" basedir=".">
    <target name="default">
        <echo message="Hello World from build.xml"/>
    </target>
</project>
pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.bluelotussoftware.example.jsf</groupId>
    <artifactId>mavenproject1</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>mavenproject1</name>
    <url>http://maven.apache.org</url>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.6</version>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <!-- Execute an ant task within maven -->
                                <echo message="Hello World from pom.xml"/>
                                <!-- Execute an ant task in an external build.xml file. It assumes the file is called 
                                build.xml and is located in the same directory as the pom.xml file. The target in
                                the external file is called default.
                                -->
                                <ant target="default"/>
                            </target>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>
Enhanced by Zemanta

Wednesday, October 27, 2010

Disabling Apache POI Logging

Jakarta POI LogoImage via Wikipedia
In order to effectively disable the logging functionality in Apache POI you must use an alternative logger. This is accomplished by providing a property to the POILogFactory to override the default logger. Examining the partial code from the POILogFactory, we see that we can pass a logger name into it.

public static POILogger getLogger(final String cat)
    {
        POILogger logger = null;
        
        // If we haven't found out what logger to use yet,
        //  then do so now
        // Don't look it up until we're first asked, so
        //  that our users can set the system property
        //  between class loading and first use
        if(_loggerClassName == null) {
         try {
          _loggerClassName = System.getProperty("org.apache.poi.util.POILogger");//<<---------- Logger Name
         } catch(Exception e) {}
         
         // Use the default logger if none specified,
         //  or none could be fetched
         if(_loggerClassName == null) {
          _loggerClassName = _nullLogger.getClass().getName();
         }
        }
...
So we need to simply set the Logger property which can be accomplished from the command line. We will use the Apache Commons Logging Library to accomplish it.
-Dorg.apache.poi.util.POILogger=org.apache.commons.logging.impl.NoOpLog
Enhanced by Zemanta

Disabling Logging on Apache Commons Logger

I was looking for a quick way to disable logging on Apache Commons Logger so that I could do some testing without overhead. Here is a command line option for setting the logger to a no-op logger.

-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog

Friday, October 01, 2010

Closures in Java 6

87.Image by Zoë Campbell via Flickr
Closure...
I met a really neat guy at JavaOne. His name is Llewellyn Falco. We met during the Java User Group (JUG) Sunday prior to the event. He was a participant in the un-conference we had set up to discuss topics of interest to the JUG community.

I was the moderator for a discussion of "languages on the JVM". The talk was slated for 45 minutes, but like all good discussions it evolved into a 4 hour talk. We started with about 12 people, and grew to half a conference hall room.

At one point we had devolved from JVM languages to simply the JVM. On my immediate right was Stephen Colebourne, and to his left was Llewellyn Falco. I asked what new features would you consider important in the JVM. Llewellyn said "closures". Stephen compiled a list of the top 10 items like: closures, continuations, AOP, Design by Contract, etc. After compiling the list, we asked the participants to pick three by vote tally on the cards for each topic. Closures won hands down.

I turned on the crowd..."Why do you want closures? What is the use case? Can you explain in simple terms what "closures" are for the common man, and why should I care?" I wanted a discussion. I wanted to make sure that I did not have a bunch of complacent sheep that wanted it because "everyone else wants it".

Llewellyn stepped up. He had an elegant explanation for closures, a use case, and clearly defined examples. He even quoted C#(EVIL...HISS!) and its use of closures. Stephen (who is more far more well versed than me), countered with some probing questions. Llewellyn did not falter, and answered the questions very quickly and eloquently.

The session ended on very pleasant terms, and we all had a great time.

Roll Forward...Two Days


I was in the JavaOne tent with Sven Reimers (Duke Award Winner and NetBeans Dream Team Member), and Martin Klähn (new community leader) chatting. Llewellyn came in with bloodshot eyes and told us he had JDK 6 "closures". He had been up late coming up with the code. He gave us a demo of what he had done. It was really cool! My partners in crime were leaving for another technical session, so I stayed and looked at the code. Finally, I came to the conclusion that something was not right. Llewellyn admitted he changed Object, and added extension methods to Object. 

This creates a "long tail" for Object which should be immutable. This is not a good idea. The question is where the extension methods end.


OK, I don't like playing with Object and using the classloader to cheat faith. His approach is cool! If you need "closures", and you can't wait for JDK 8; this is a solution. I am not opposed to improving developer productivity, I am just concerned about the extension of Object.


Please read Llewellyn Falco: Lamdbas in Java 1.6 blog on it. It is very well written, and offers the developer options. 

Thanks Llewellyn and Stephen! You are both awesome and brilliant. I am humbled at your great ideas, and I think we all have an opportunity to learn from your ideas.
Enhanced by Zemanta

Thursday, September 30, 2010

WebP: Why settle for less

Image representing Google as depicted in Crunc...Image via CrunchBase

Cnet broke the news this morning about Google's WebP technology which is a "lossy" image codec which can reduce a image to about 40% smaller than a JPEG. The premise is that the more images that a consumer can look at, the more money that Google can rake in.

Does anyone else find this a cheap bait-and-switch?

I like to think I am open to new technologies, but this seems like a blatant downgrade of our current technologies. Yes, their could be an argument for smaller images for cellular phones and limited network bandwidth.

I want better images! I want images where you can enlarge them, make them a wallpaper, or show your kids; and I don't want them "lossy" 40% less than a JPEG.

I will need to wait for complete judgment until there is a browser which supports it so I can compare them with other image formats.

Until then, thanks Google with about 40% less enthusiasm.


Enhanced by Zemanta

JavaOne 2010: JavaFX Roadmap

JavaFX MobileImage via Wikipedia
I published an article earlier today on JavaFX, and avoiding the Kool-Aid. I have since discovered a published road map for JavaFX. I am still warning you not to invest until the goods are out, but here is the published road map.

JavaFX: Future Roadmap 2011+
Enhanced by Zemanta

JavaOne 2010: JDK7 Milestones

It has been a week since JavaOne. I am on the OpenJDK site looking at the plans for JDK7, and it is still empty with no updated plans. Only an orange text box promising an update to the milestones.

There were enough repetitive presentations, and probably discussions behind the scenes prior to JavaOne. Where is the plan? You can check it out yourself at the link below.

JDK7 Milestones

Enhanced by Zemanta

JavaFX: Why you should not drink Kool-Aid

JavaFX MobileImage via Wikipedia


F3 (Form Follows Function) was the original name of the language in 2005. Now we are 2010, and JavaFX (new name) is still yet to be realized. I started development with JavaFX in alpha/beta stages. When the first official release came out, all my code broke with Scenes, and Stages. The code was released incomplete, and failed to have at least a minimum matching set of components for Swing.

Now after 5 years, Oracle has decided to "kill" the scripting. The license is not open, and they expect us (developers) to trust "JavaFX 2.0+"?

I drank the Project Woodstock (Visual JSF) and JavaFX Kool-AId. Shame on me for not learning the first time.

I am going to wait and see, but Q3 2011 is probably to late for me... and JavaFX.
Enhanced by Zemanta

Friday, September 17, 2010

On the Cusp of JavaOne

JavaOne begins for me tomorrow (Saturday) with an annual event. The Java.Net Community Leaders Saturday. It is a working day for the community leaders to meet once per year to look at the challenges our communities face, and to plan for the upcoming year. It is also a time to re-kindle friendships, and share fellowship. I head out tomorrow morning to begin JavaOne 2010.

On Sunday, the JUG leaders and Java Champions are doing Java User Group Community Sunday along with MySQL, and GlassFish Community events. It is our hope that we can cross-pollinate our communities which are very intertwined.

The JUG Community Sunday event is promising to be a great affair. We have set it up as an Un-conference. So topics are open for the community. Instead of one person, or group projecting ideas at you, we can share ideas and let the cream float to the top. What is most important to the community. I can imagine that legal issues will float up. It is all I hear about from my community. I can't imagine it is different elsewhere. 

The conclusion of the Sunday events culminates in a couple of cocktail parties, an Oracle reception, and GlassFish party at the Thirsty Bear.

I almost forgot, Oracle is having a brunch for the Java User Group (JUG) leaders, and Java Champions. This will be a great chance for meeting new leaders, and reuniting with friends, and meeting the Oracle community.

All of these events take place before the official kick-off on Monday. Are you coming to JavaOne? Why not?
Enhanced by Zemanta

Google Buys Instantiations

Google Web ToolkitImage via Wikipedia
It is interesting that Google acquired the GWT Designer, and Eclipse tools from Instantiations. Is this a sign that Google does not have any worries about the Oracle lawsuit. I don't think this is the case, I feel that it is in their business interests, and "lawsuit be dammed" they are going to continue doing what Google does. Albeit, they do it well.

I am not a GWT user, but it does offer developers other UI options, and options are good. This is especially true with Google; their options are generally very good.
Enhanced by Zemanta

Illumos: An OpenSolaris Replacement, or Vaporware

OpenSolarisImage via Wikipedia
OpenSolaris Logo
The end of the OpenSolaris project was cold blooded, and rather uneventful. Is that because we saw it coming, or has the relevance of OpenSolaris questionable?

There is no doubt that OpenSolaris was the barometer of where Solaris should be heading in an open source world. It included an incredible tool set, and an opportunity to contribute to a great project. The unceremonious end at the hands of Oracle is a brutal barometer to its intentions with regards to open source. This has nothing to do with its current legal battles with Google which is by no means innocent in those legal proceedings.

It was announced in SD Times, and in the Twitter space that Illumos was going to take up the banner for the OpenSolaris cause. As of today, there are no binaries, or code. I am not sure if the legal proceedings have killed the project, or seriously given the project owners a case of heartburn.

The last news is that it will support Mono. This news is least bit interesting to me, and actually I think I caught a chunk in my throat.

I like the idea of continuing the open source development of OpenSolaris, but I am wondering if it is going to fall under the veil of a legal clouds, or a Chinese puzzle box of legal quagmires. Let us not forget that Mono is a bulls-eye for Microsoft.

What are your thoughts?

Signed,

The disaffected, and disillusioned OpenSolaris advocate.
Enhanced by Zemanta

Sunday, September 12, 2010

JRuby and Rails 3

Rails 3.0 has been released. I know a number of you are excited about all of the possibilities. Along with the release of Rails is a new point release of JRuby.  So the big question is how do you use them together.

The default Rails environment uses SQLite as the database. Let me show you how to get started.
Riding on JRuby on Rails

  1. Start by downloading JRuby, and install it.
  2. Once it is installed you will want to install jruby-openssl.
    jruby -S gem install jruby-openssl
  3. Next lets install the SQLite database gems.
    jruby -S gem install jdbc-sqlite3 activerecord-jdbc-adapter \
    activerecord-jdbcsqlite3-adapter

  4. Once we have installed the gems for SQLite, we can install Rails.
    jruby -S gem install rails mongrel warbler
  5. Now that Rails is installed, we can create our example application. This will create our application.
    jruby -S rails new blog
  6. Next we replace the following line in the Gemfile

    gem 'sqlite3-ruby', :require => 'sqlite3'

    with the following:

    if defined?(JRUBY_VERSION)
    gem 'jdbc-sqlite3'
    gem 'activerecord-jdbc-adapter'
    gem 'activerecord-jdbcsqlite3-adapter'
    gem 'jruby-openssl'
    gem 'jruby-rack'
    gem 'warbler'
    else
    gem 'sqlite3-ruby', :require => 'sqlite3'
    end

    This allows us to run the application in JRuby, or Ruby.
  7. Next we need to modify the config/database.yml file.

    # SQLite version 3.x
    # gem install sqlite3-ruby (not necessary on OS X Leopard)
    development:
    adapter: jdbcsqlite3
    database: db/development.sqlite3
    pool: 5
    timeout: 5000

    # Warning: The database defined as "test" will be erased and
    # re-generated from your development database when you run "rake".
    # Do not set this db to the same as development or production.
    test:
    adapter: jdbcsqlite3
    database: db/test.sqlite3
    pool: 5
    timeout: 5000

    production:
    adapter: jdbcsqlite3
    database: db/production.sqlite3
    pool: 5
    timeout: 5000

  8. Next we need to migrate the database.
    jruby -S rake db:migrate
  9. Finally we can start our new Rails 3 application.
    jruby -S rails server
That's it. You are riding on Rails in 9 steps.

References:


Enhanced by Zemanta

Saturday, September 04, 2010

Programming with Reason...

First graphical user interface in 1973.Image via Wikipedia
First Graphical User Interface
I just read an article in Dr. Dobb's entitled Programming with Reason: 1. The article does not cover any new ground. I have read these programming mantras before. However, it is often mentioned that the more you see something, you are more likely to remember it; marketing.

Anyway, the general programming rules are:

  1. Simplicity: design programs to do exactly what they need to do and no more.
  2. Elegance: simple programs which do what they need to do an do no more are elegant. This can be achieved by abstraction, and encapsulation.
  3. Graphical User Interfaces (GUI): a simple elegant program must have the same aspects in its interface. The author, and I have both admittedly created a "quick" mock-up for an interface only to have it become the final one. The eyes are the path to the soul, and your GUI is the path to your program. Don't create a bloodshot allergenic interface unless you want to hurt your users eyes.

Again, nothing new here, but something worth reminding all of us to take into consideration everyday.
Enhanced by Zemanta

Friday, August 20, 2010

SerialVersionUID Generator for NetBeans

Are creating serialVersionUID values getting you down?

I have been using 's SerialVersionUID Generator For NetBeans tool for a couple of years now. It used to be available for download from the NetBeans update site, but version 1.9.6 for NetBeans 6.9 has not been available. The current version for use with NetBeans 6.9 can be downloaded from here: eu-easyedu-netbeans-svuid-1.9.6.nbm

This fantastic plug-in is great for generating the serialVersionUID values as part of the Serializable interface contract. If you are doing work with Java Persistence API (JPA) you will definitely want this little plug-in to make your life easier.

  1. You will get a hint on the class about the missing serialVersionUID if you implement Serializable.
  2. Right-click on the class and pick from two options:


    • Add default serialVersionUID
    • Add generated serialVersionUID
Enhanced by Zemanta

Why Movable Type, Drupal, or Wordpress on GlassFish?

WordPressImage via Wikipedia
Image representing Movable Type as depicted in...Image via CrunchBase

The question of relevance has come up on why would you implement Movable Type, Drupal, or Wordpress on GlassFish. Is it because you can?


The answer is one of technology fundamentals and implementation strategies. I am a Java developer (if you could not figure that out from the blog title). I have access to GlassFish which I use for all of my web based application deployments. I want to be able to simplify my administration requirements by using a unified deployment platform. I also want to be able to combine the extensive libraries and frameworks that are available for Java. I want a simple intuitive administration console to handle most of my day-to-day needs. I want administration, and deployment to be scriptable. GlassFish solves a number of these issues, along with using Java, and Java based implementations of some popular languages like JRuby, and Jython.

First, GlassFish versions 2 and 3 are the reference implementations for Java Enterprise Editions (EE) 5 and 6 respectively. If you are doing enterprise software development, and want to use the latest reference versions, you should use GlassFish. I often write about Java Enterprise Edition (EE). I try to focus on the core technology since this keeps it compatible across other EE containers should you choose to move it to another container. GlassFish version 3 has made a number of positive steps in JEE 6 to make it easier to use. The new profiles in GlassFish make it easier to do web development.

Apache web server is very powerful. There is no question about that, but installing modules, and configuring it is not simple. If a module is not available in one of the pre-configured and installed versions on your system, you must compile it yourself. I am a very competent Apache administrator, and I have never had a simple download, and compile deployment. Let me contrast that with GlassFish, if you have Java 6 installed on your system, download and run it. If you are using JRuby, or Jython, GlassFish can handle it right out  of the box. In the case of JRuby, there have been a number of performance tests to show JRuby on Glassfish is faster that Ruby on WEBrick, or Mongrel. The Common Gateway Interface (CGI) servlet will allow you to take advantage of additional CGI technologies with simple configuration on a server wide basis, or on a per application basis.

Apache Web Server and GlassFish can take advantage of a number of frameworks. Apache Web Server can run Ruby applications with the appropriate module. However, it can not take advantage of other independent frameworks. Java on GlassFish allows Ruby developers to use Java frameworks like Swing within their applications. You can even create polyglot applications which use JRuby, Jython, and Clojure. This may be possible  with Apache Web Server, but I am unaware of it. This is a comment point for readers.

Simple and Intuitive administrative interface. That describes GlassFish administration console to a tee. I would even include elegant, and beautiful.

GlassFish Administration Console

Glassfish includes a very complete command-line interface. Anything you can do on the GUI based interface, you can do from the command-line. It also includes a number of advanced features which are not available in the adminstrative GUI.

Finally, as I noted above it has multiple configuration points with languages and technologies including Microsoft technologies.

I have found that GlassFish handles all of my Web based needs in a single platform. This combination of technology and integration points makes it easy to install relevant best of breed software like Drupal, Movable Type, or Redmine on the same platform and integrate functionality between them as necessary. It is very nice to have Redmine and Hudson CI running on the same platform. Combine it with Mercurial, and share a common SSO. This is not done easily on Apache Web Server, or any other platform.

I hope this clarifies my position on its relevance with Movable Type, Drupal, Wordpress, etc.
Enhanced by Zemanta

Popular Posts