David R. Heffelfinger

Bookmark and Share
Saturday Feb 13, 2010

Groovy Script to find Java classes in JAR files


We've all been there at some point or another. We just inherited a big pile of legacy Java code that we need to maintain. This code likely is using some big convoluted ANT script to be built. This being legacy code, it does not use a dependency manager like Ivy or the one included with Maven.

We, of course, want to be able to build using our favorite Java IDE, be it Eclipse, NetBeans or IntelliJ IDEA. Our Java IDE, of course, has no idea of what our project dependencies are, therefore our code is riddled with squiggly red lines due to missing dependencies all over. We are going to manually add dependencies to our project, oh joy. In many cases, these dependencies are scattered across multiple directories, we may have to inspect the contents of most of our JAR files to find many of our dependencies, especially those built in-house.

I was recently in this situation myself, to ease my pain, I came up with a Groovy script that recursively inspects every JAR file in the current directory and every subdirectory. It takes a single parameter, the name of the class to look for (case sensitive), then recursively checks every JAR file in the current directory all subdirectories. It's only requirement is that the "jar" executable be in the PATH, which should be the case for most Java programmers anyway.

Without further ado, here is the script. Enjoy

#!/usr/bin/env groovy
def cDir = new File(".");
def jarContents;
cDir.eachFileRecurse{file ->
if (file.name =~ /.*\.jar$/)
{
jarContents = "jar tvf ${file}".execute().text;
jarContents.eachLine{line ->
if (line.contains(args[0])){
print "*** found in ${file.canonicalPath}:";
println line;
}
}
}
}

Tuesday Feb 02, 2010

Groovy Script to SFTP files using AntBuilder and Grapes

Recently I needed to write a Groovy script to SFTP a file to a server. With a little bit of googling, I came to the conclusion that the easiest way to do that was to use AntBuilder ANT's scp task.

Since this script is going to be used by several people, I wanted to use groovy Grapes to pull the dependency automatically.

Turns out that AntBuilder doesn't see dependencies pulled with the Grab annotation, after a little bit of some more googling I found the solution. Instead of using the @Grab annotation, use the static grab() method of the Grape class to pull the dependencies, this allows us to specify that we need the rootLoader as the class loader, which AntBuilder can see.

Without further ado, here is the script in it's entirety for your copying and pasting pleasure:

#!/usr/bin/env groovy
import groovy.grape.Grape;

Grape.grab(group:"ant", module:"ant-jsch", version:"1.6.5", classLoader:this.class.classLoader.rootLoader)
Grape.grab(group:"com.jcraft", module:"jsch", version:"0.1.42", classLoader:this.class.classLoader.rootLoader)

def ant = new AntBuilder();
def pw;

print "password: ";
//the following line does not work under Cygwin, System.console() returns null
pw = System.console().readPassword();
def pwStr = new String(pw);
ant.scp(trust:'true',file:"/path/to/file.txt",
todir:"user@host:/home/user",
password:"${pwStr}",verbose:"true");




Thursday Oct 08, 2009

PDF Unlock Utility Tutorials in Youtube

Lately I've been noticing some referrals from YouTube in my server logs. Curious about it, I looked into it and turns out there is not one, but two video tutorials explaining how to use my free online PDF unlock utility, both of them in Spanish.

 





Ogling Android Phones

I'm a long time BlackBerry user, however for a while I've been tempted by the Android platform. The openness of the platform seems very attractive to me.

The other day I went to the T-Mobile store to try the MyTouch 3G, unfortunately I wasn't very impressed with it. The problem I had was with the virtual keyboard, the wrong letters would show up when I pressed most keys. I looked around online to see if this was a common complaint about the device, and couldn't find much about it. Maybe the unit I tried at the T-Mobile store was defective. Nevertheless, I figured the MyTouch's virtual keyboard would be a recipe for frustration, so I stuck to my BlackBerry Bold for the time being.

Browsing around the web I learned that Sprint will get two new Android phones soon. The HTC Hero, which got a glowing review from ZDNet is coming out this Sunday, October 1st. Based on the review I got really tempted to get one.

While doing some more research I also found out that another Android phone, the Samsung Moment will be released on November 1st, three weeks after the Hero.

I've been researching both devices and at this moment I think I would prefer the Samsung, since it has a much faster processor (800 Mhz, vs 528 Mhz for the Hero) and a physical keyboard. It also seems to come with a more "Standard" Android OS, which I think would make it easier to upgrade the device with future versions of Android.

The Hero comes with "value added" software from HTC, which, although it may be very nice, it may make it harder to upgrade the OS in the device, if nothing else for fear of losing the HTC specific software. Other advantages of the Hero include slightly more memory (288 MB vs the 256 MB that the Moment has), and a 5 megapixel camera (vs the 3.2 megapixel that the Moment has). On the flip side, the Moment's camera has a flash but the Hero's doesn't.

Both seem like very nice devices, but the much faster processor and the physical keyboard of the Samsung Moment, plus the apparent ease of upgradability of the Hero tilt the scale in favor of the Samsung device, at least in my book.

I also looked at Sprint's plans and they seem to have some good ones. I like AT&T's rollover minutes which Sprint lacks, however Sprint's data plan includes GPS functionality, which AT&T charges extra for; and live streaming video through  Sprint TV, which as far as I know AT&T lacks. Also, with Sprint I can make and receive any domestic cell phone number from any carrier. Most of the calls I make and receive are to/from mobile phones anyway, so this is a big plus for me.

I'll be dropping by my local Sprint store in about three weeks to test the Samsung Moment out.


Tuesday Sep 22, 2009

Maven pom.xml configuration for Servlet 3.0

Good old servlets are getting a facelift in the next major version of Java EE after been somewhat neglected for so long.

One of the major changes of the new Servlet 3.0 API is that a web.xml is no longer required. Instead, servlets can be configured directly in the source code via annotations.

I wanted to try out this new feature, deploying in GlassFish 3 preview, which is the only Java EE 6 compliant application server at the moment.

As usual, I created a Maven project to test out this functionality, unfortunately, nobody has told Maven that a web.xml is no longer required. My build was failing with Maven complaining about the lack of a web.xml.

After some research, I found out how to configure Maven to avoid it complaining about this non issue.

Here is my pom.xml in it's entirety.

<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>net.ensode.glassfishbook</groupId>
<artifactId>simpleapp</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>simpleapp</name>
<url>http://maven.apache.org</url>
<build>
<finalName>simpleapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1-beta-1</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>java.net</id>
<url>http://download.java.net/maven/2</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

Notice that I'm using the Maven war plugin version 2.1 (in beta at the moment), since previous versions of the plugin (like the default 2.0) do not support the <failOnMissingWebXml> tag yet.

Thursday Aug 13, 2009

JasperReports 3.5 For Java Developers Published

I'm proud to announce that the second edition of my JasperReports book, JasperReports 3.5 for Java Developers has been published.

The book has been updated to cover the latest features added to JasperReports since the first edition was published. Here is the table of contents:

Chapter 1: An Overview of JasperReports
Chapter 2: Adding Reporting Capabilities to our Java Applications
Chapter 3: Creating your First Report
Chapter 4: Creating Dynamic Reports from Databases
Chapter 5: Working with Other Datasources
Chapter 6: Report Layout and Design
Chapter 7: Adding Charts and Graphics to Reports
Chapter 8: Other JasperReports Features
Chapter 9: Exporting to Other Formats
Chapter 10: Graphical Report Design with iReport
Chapter 11: Integrating JasperReports with Other Frameworks

The full table of contents can be found here.

I also added JPA integration as part of the chapter on JasperReports integration with other frameworks.

An article based on the book can be found at the Packt Publishing web site, it covers the most common use for JasperReports, which is generating reports from database data.

Also, chapter 10, Graphical Report Design with iReport, is available for free, no registration required.


Friday Aug 07, 2009

Java DB / Apache Derby: Insecure By Default

Both JDK 1.6 and GlassFish come bundled with Java DB, which is nothing but a rebranded Apache Derby RDBMS. If you have ever done anything with Derby, you know that a database can be created by simply by passing the create attribute with a value of true. For example, to create a database on a server called myserver.com, all that is needed is to use the following JDBC URL:

jdbc:derby://myserver.com:1527/mydb;user=foo;password=bar;create=true

The above JDBC URL will create a database called "mydb", and, in Derby/Java DB, the default schema matches the user name, so the above URL will create a schema called "foo" and set it as the default schema.

This is great in the sense that creating a database is very easy, but it is not so great in the sense that it allows anybody to create a database on the server and do whatever they want with it.

If this wasn't bad enough, by default passwords are ignored, therefore, with the default configuration in place, anybody can connect to the database as user "foo", for example, the following JDBC URL would connect you just fine:

 jdbc:derby://myserver.com:1527/mydb;user=foo;password=aaa

Notice that in this second JDBC URL, the password is different than the one we used when we created the database, it doesn't matter, in the default Derby configuration, the password is ignored, it is as if it didn't exist, therefore this URL would allow us to log in just fine.

Standalone Derby / Java DB only listens for connections from localhost, so in this case the default behavior is not too bad (there is still some security risk in a server with multiple users, however random people cannot connect through the network and create databases/log in to a database willy nilly).

However, GlassFish comes bundled with Java DB/Derby. When starting the database through GlassFish's asadmin utility:

asadmin start-database

The database by default listens accepts network connections. Unfortunately all other (lack of) security defaults stay in place, therefore with GlassFish's JavaDB's default configuration, random Joe's out there can connect to our databases without using a password, and can also create their own databases. This is a major security hole.

Luckily, Java DB/Derby can be easily configured to require valid user credentials, it is unfortunate that it is not configured this way by default. There are various ways to configure authentication in Derby/Java DB, it can be "hooked up" to an LDAP server, additionally, custom code can be written to handle authentication, and finally, a property file can be written set up authentication. The Derby Developer's Guide has all the details, in this entry, I'll just explain the simplest way, in case you are panicking because I just made you realized your database is exposed to the world.

The property file to create to enable authentication has to be called derby.properties it should look something like this:

derby.connection.requireAuthentication=true
derby.authentication.provider=BUILTIN

# Users definition
derby.user.someusername=password1
derby.user.john=doe

derby.connection.requireAuthentication=true tells Derby/Java DB that authentication is required.

derby.authentication.provider=BUILTIN sets up Derby to use its internal, built-in authentication mechanism.

After setting the above two properties, we need to add some users, they are added as shown in the above sample derby.properties file, properties preceeded by "derby.user." are understood to be users, the user name is the string immediately following "derby.user.", and the password is the value to the right of the equal sign. For example, if we wanted to add another user with a username of "joe", and a password of "secret", we would add the following line to derby.properties:

derby.user.joe=secret

Once we have created this file, we need to put it in $DERBY_HOME/bin if we are using the standalone Java DB/Derby or the Java DB version that is bundled with JDK 1.6. Java DB is placed under $JAVA_HOME/db in in Linux and under C:\Program Files\Sun\JavaDB in Windows.

If we are using the Java DB version that is included with GlassFish, then the derby.properties file needs to be placed under $GLASSFISH_HOME/databases, where $GLASSFISH_HOME is the directory where GlassFish is installed.

After copying the file to the appropriate location, the Java DB/Derby needs to be restarted for the changes to take effect.

Saturday Aug 01, 2009

Groovy Script to zip a directory excluding certain files and subdirectories

Like I mentioned in my last post, I've been reading about Groovy lately. I'm finding Groovy very useful to automate small tedious tasks that I have to do in a regular basis.

For example, many times I have to zip up a directory, but there are some files or subdirectories I want to leave out. What I usually did was I would zip up the whole directory, then manually delete whatever I didn't want in the zip file. Alternatively, I would try to do it from the Linux command line, but I invariably would forget the syntax to do it, this would happen so often that I wrote a blog post explaining how to do it primarily so that I could refer to it myself.

ANT has a zip core task that can easily exclude files or directories from the resulting zip file, through Groovy's AntBuilder class, it is trivial to write Groovy scripts to invoke ANT tasks. It didn't take long to put two and two together, and write a simple Groovy script that would invoke the ANT zip task, specifying any unwanted files or directories.

Without further ado, here's the script:



#!/usr/bin/env groovy
def excludes="**/*.swp, somefile.txt, somedir/**"
def ant = new AntBuilder()

println "args = ${args}"
if (args.length > 0) {
if (args[0].endsWith("/") || args[0].endsWith("\\")) {
args[0] = args[0].substring(0, args[0].length() -1)
}
ant.zip(baseDir:args[0], destFile:args[0] + ".zip", excludes:excludes,
update:true)
}
else {
println "usage: ZipDir.groovy [dirName]"
}

Simply edit the value of the excludes variable to contain any valid comma-separated ANT patterns matching the files or directories you want to exclude from the zip file. Enjoy.

Thursday Jul 30, 2009

Groovy Script to Find and Replace Text


Lately I've been reading a bit about Groovy .Today I had to do a search and replace across several files, and decided to put my newly found Groovy knowledge to use. I wrote a simple script to search all files with a given extension, and search and replace a String inside each file.

I know this can be accomplished as a one liner, but I don't want to try and remember the syntax every time I need to do it. Also, there may be a "groovier" way to do it, being primarily a Java developer I don't really know (and quite frankly, I don't care that much, it works). Without further ado, here is the script for your copying and pasting pleasure:

 

#!/usr/bin/env groovy

def currentDir = new File(".");

def backupFile;
def fileText;

//Replace the contents of the list below with the
//extensions to search for
def exts = [".txt", ".foo"]

//Replace the value of srcExp to a String or regular expression
//to search for.
def srcExp = "dummy"

//Replace the value of replaceText with the value new value to
//replace srcExp
def replaceText = "awesome"

currentDir.eachFileRecurse(
{file ->
for (ext in exts){
if (file.name.endsWith(ext)) {
fileText = file.text;
backupFile = new File(file.path + ".bak");
backupFile.write(fileText);
fileText = fileText.replaceAll(srcExp, replaceText)
file.write(fileText);
}
}
}
)



I could have made it a bit "fancier", taking command line parameters and what not, but this is just a simple script I solved to have a simple immediate problem I was having. With a couple of simple changes it can be adapted to search different file types, search and replace strings. Enjoy.

Friday Jun 26, 2009

NetBeans Visual Web Pack Dead, What a Shame


One of the features I really liked about NetBeans was it's Visual Web Pack (VWP) functionality, it allowed developing the GUI of a JSF application by simply dragging and dropping components from a palette into the page.

Although I have no trouble actually typing code or markup by hand, especially with a  good code editor such as the one provided by NetBeans, the convenience of VWP didn't stop with the visual drag and drop.

When creating a VWP page, a managed bean was created automatically, and automatically added to faces-config.xml. Although on the surface this sounds simple, it was a big time saver. Additionally, a database table could be dragged to some of the components, and a lot of "plumbing" code was automatically generated to display or update, as illustrated in this tutorial.

Visual Web Pack used the Woodstock JSF component library, in October 2008, Sun announced that it would be abandoning project Woodstock, but luckily provided a migration path to IceFaces, going as far as having IceFaces provide a VWP plugin for NetBeans. Unfortunately it looked like this was the beginning of the end of VWP.

I actually used the IceFaces VWP NetBeans plugin for a small project, although my initial impression of the NetBeans IceFaces plugin was less than favorable, after a while I started liking it. Lately, I've been using the NetBeans 6.7 release candidate, one of the first things I did after installing this version of NetBeans was to get the IceFaces NetBeans plugin for it. To my surprise and dismay, it does not provide Visual Web functionality.

It is really unfortunate that for whatever reason, IceFaces decided to drop support for visual web development, as far as I can tell, all their current NetBeans plugin does is provide a palette that introduces markup to JSF pages (mind you, this is not visual), and include the IceFaces libraries in any JSF project declared to use IceFaces.

NetBeans Ice Faces plugin screenshot 

Dragging and dropping into markup is not really that useful, we can simply type an opening angled bracket ("<") and hit ctrl+space to see all the JSF tags we can use, this is actually faster than moving the hand to the mouse, scroll the components in the palette up and down until we find the one we need, then drag it and drop it to the appropriate location on the page.

The one thing I will miss the most is the automated managed bean generation, in practice, I rarely used the feature where a database table could be visually linked to a JSF component since th generated code was a bit convoluted an unusual. I want to say it used JDBC, but this is not exactly accurate, it used a VWP specific concept of a dataprovider to link the database data to the component, I tend to use JPA in my Java EE projects, the fact that the database table drag and drop functionality did not generate JPA code kept me from using it in my project.

In any case, it looks like VWP is dead, long live VWP!

Sunday Jun 07, 2009

A Slightly Biased Comparison Between Wicket and JSF

Recently I will start working on a project using Wicket. I used Wicket briefly in the past, I wrote an article about it and even worked as a technical reviewer for a book on Wicket, but I have never used it in production systems.

On the other hand, I have written two books that cover JSF, I also teach a class that covers JSF development, and I have worked on some projects that use JSF in production. As the author of two books that cover JSF, I have a vested interest in having JSF remain popular, therefore I am obviously somewhat biased, however I'll try to be as objective as possible when making this comparison.

All of my Wicket experience happened a few years ago, I haven't used it much in about three years, so for the past few days I've been refamiliarizing myself with this framework.

When comparing Wicket with plain vanilla JSF wicket is the clear winner. The fact that the markup in Wicket is plain HTML (with special wicket specific attributes) makes Wicket much more accessible, since no special knowledge of Wicket components is needed to come up with the markup. This allows web designers to do what they do best, design their user interfaces with their preferred tools such as Dreamweaver or other web design tools. The changes to the markup to make it work with Wicket are minimal, the wicket specific attributes need to be added to HTML tags that will be replaced at runtime with Wicket components. However, very few people use "vanilla" JSF. Most JSF developers use a component library such as ICEFaces or RichFaces. Furthermore, Facelets is a very popular view technology that can also use standard XHTML to develop JSF views. When component libraries and Facelets enter the picture, picking a winner is not so easy.

The fact that Wicket uses standard HTML for its markup may be an advantage or a disadvantage depending on your situation. If you are working with a professional web designer, then having straight HTML as markup is a real advantage. However, if your team consists primary of Java developers with little or no web design skills, then using a JSF component library that renders its pages using predefined CSS and Javascript, then in this case JSF may have the advantage.

Wicket reminds me a lot of working with Facelets, when using Facelets, we can develop pages that are plain XHTML, however we are not prohibited from using JSF specific tags. When previewing a Facelets page in the browser, the JSF specific tags are simply ignored.

Wicket also has some Wicket specific tags, however they are used to ignore parts of the HTML when it is rendered in the browser and other functionality, they are not really meant to be rendered. On the other hand, HTML tags in Wicket can have an wicket id corresponding to a component that renders HTML on the page, for example, a <span> tag could map to a custom Wicket component, therefore, a Wicket page may not preview exactly like it will be rendered when the application is deployed, which is the case with Facelets as well.

My impression on which one is better is, like in most cases, it depends. If a professional web designer is available, then Wicket may be the better choice, however if most of the development team are backend Java developers, then using JSF with Facelets plus a component library such as IceFaces or RichFaces may be a better choice.

Saturday May 23, 2009

Confessions of a Java Snob

For the past couple of months I've been working on porting a PHP application to Java EE using JSF, JPA and EJB 3 (in case you are wondering, yes, I've been using NetBeans and GlassFish).

I've never had any real exposure to PHP, so this is a new experience for me. I'm not sure if what I'm seeing is typical PHP code, but comparing this legacy system to the typical enterprise Java system shows some striking differences in architecture. When analyzing the PHP code, it became obvious to me that the mindset of PHP developers is very different from your typical Java developer.

In the Java world, we love our design patterns, we can't live without our DAO's and MVC. In PHP, it seems to be no big deal to mix presentation, business logic and data access in a single file.

Having worked with Java for over 13 years and Java EE/J2EE for about 10 years, I have to confess that the architecture (if you can call it that, more like "lack of architecture") seemed appalling to me. In the enterprise Java world, we've been conditioned to think that separation of concerns is a good thing.

Our presentation logic should contain presentation only, that way if in the future we want to switch say, from straight JSPs and servlets to JSF, the rest of the code shouldn't be affected. Additionally, if we want to convert our web application to a desktop application using Swing, it should be fairly straightforward to do so.

Data access logic should be done via Data Access Objects (DAO's), that way if today we are using straight JDBC and tomorrow we want to use an object relational mapping tool such as JPA or Hibernate, all we need to do is change the data access layer, the rest of the code should not be affected.

Communication between layers in our applications should be done via Value Objects, which shouldn't really change if we change our data access layer or presentation layer.

Controllers should manage flow from one page to another, again these should only be rewritten if we change our presentation layer. Most Java web application frameworks provide their own controllers, however they are not self sufficient, for example, in Struts we need to use Actions and in JSF we need to write managed beans, therefore changing the presentation layer would usually involve changing the controller as well.

After analyzing the code for the legacy system I got the impression that PHP is a language for amateurs and Java/J2EE/Java EE is for professional software engineers and architects. Am I right? Or I am just a Java snob? Feel free to set me straight.

Saturday Apr 25, 2009

Ubuntu Jaunty Jackalope on an HP dv6000 laptop

Ubuntu 9.04 (aka "Jaunty Jackalope) was released earlier this week.

Today I set away some time to install it on my laptop, an HP dv6810us, part of the Hewlett Packard dv6000 series.

Almost everything worked "out of the box", unfortunately the wireless still takes some work to set up.

In the past I had been using ndiswrapper
to get it to work. This time it wasn't necessary, but it still took
some effort to get it going. It would be nice if the wireless would
work out of the box.

In any case, lspci -v returns the following information for my wireless card:

03:00.0 Ethernet controller: Atheros Communications Inc. AR242x 802.11abg Wireless PCI Express Adapter (rev 01)
    Subsystem: Hewlett-Packard Company Device 137a
    Flags: bus master, fast devsel, latency 0, IRQ 19
    Memory at f6000000 (64-bit, non-prefetchable) [size=64K]
    Capabilities: [40] Power Management version 2
    Capabilities: [50] Message Signalled Interrupts: Mask- 64bit- Queue=0/0 Enable-
    Capabilities: [60] Express Legacy Endpoint, MSI 00
    Capabilities: [90] MSI-X: Enable- Mask- TabSize=1
    Capabilities: [100] Advanced Error Reporting <?>
    Capabilities: [140] Virtual Channel <?>
    Kernel driver in use: ath5k
    Kernel modules: ath_pci, ath5k

I googled around to see if I could find a solution, and bumped into this thread in the Ubuntu forums. The thread is for Intrepid, but I thought I would adapt the solution to Jaunty and see if it worked.

apt-get install linux-backports-modules-jaunty

Rebooted and... nothing!

Since
the solution didn't work, I uninstalled the above package and, lo and
behold, like magic and for no apparent reason, the wireless started
working!

I suspect that one of the dependencies on that package
did the trick, I'm not sure which one (I can't even remember which
dependencies were automatically downloaded), but installing the above
package, then uninstalling it did the trick. Weird, but it worked.

Now wireless is working without ndiswrapper.

Other
than the wireless, the installation was very smooth. Ubuntu
automatically detected my Nvidia card on the first boot, and asked me
if I wanted to install the restricted drivers. I did, rebooted and the
driver "just worked".

Also, boot time is amazingly fast, which is very nice.

Sunday Apr 12, 2009

Preventing Trackback Spam in Apache Roller

This morning I woke up to find 150+ comments in one of my blog entries. I have email notification of comments set up in Roller, so the 150 emails notifying me of comments in my blog indicated that something was obviously not right.

I logged in to my blog to see what is going on, and sure enough, I had over 150 bogus trackbacks in one of my blog entries.

I googled around, and found a way to prevent trackback spam in Apache roller, going to "Main Menu", then clicking on "Server Administration", then checking "Enable verification of trackback links?" and "Enable referrer linkback extraction?" seems to have taken care of the problem.

Roller should really have those two settings checked by default.

Also, I noticed all the bogus trackbacks were coming from the same IP address (83.233.30.32). I googled around, and it looks like many others are having problems with spam from that IP address as well. Just to make extra sure, I dropped any incoming traffic from that IP by configuring IP Tables:

iptables -A INPUT -s 83.233.30.32 -j DROP

iptables-save > /etc/sysconfig/iptables

Hopefully the problem is taken care of for good.

Sunday Mar 15, 2009

How do kids these days get started in programming?

Back in the 80's, when I was growing up, all personal computers would come with a BASIC interpreter which you could use to write your own software. As a matter of fact, it was expected for end users to write their own applications.

My very first personal computer was an Atari 800,  I was in my early teens when I got it, it was a hand me down from my uncle, who had gotten himself a shiny new IBM PC.

 Atari 800

During that time, computer magazines came with games and applications in source code form that you had to type into your computer in order to "install" them. A lot of us didn't know exactly what all these lines of code meant, but we wanted the game or application so we typed away, unfortunately typos were an issue, since we were just blindly copying what seemed like greek into our BASIC prompt. Fortunately BASIC was interpreted, so it would catch syntax errors immediately, but many times the syntax was correct, but there was still a typo in the line, making the program not run as expected. It could be frustrating at times, but it was very satisfying to finally get the code to work exactly right. You could also experiment and make little changes here and there to see if you could change the behavior of the software. I remember eagerly waiting for the next issue of A.N.A.L.O.G magazine to arrive in the mail every month to see what goodies it would bring.

It is worth mentioning that at this time there wasn't yet a dominant computer architecture for personal computers. Some of us had Ataris (8 bit and/or ST), others had Commodores (PET, Commodore 64 or 128, Amiga), others had IBM PCs, other architectures existed as well. What all of these architectures had in common was that they all came with a BASIC interpreter. As a matter of fact, in most cases, the machine would boot directly into a BASIC prompt. The BASIC versions of the machines were not 100% compatible across one another, since vendors modified them to highlight specific features of their own products, but in general your BASIC skills could be used across architectures.

I remember been amazed at the wonderful things you could make these machines do, it got me really motivated to learn to write my own software, not simply blindly typing code listings from magazines. A lot of software developers from that era got our start that way, at the time, the barrier of entry for software development was very low. I derived a lot of satisfaction in creating software, I would proudly show my creations to my friends and relatives. All of these got me motivated to pursue a career in software development, which is what motivated me to major in computer science when I went to college.

Somewhere in the 90's most of these various architectures disappeared, and the one true personal computer platform emerged, the IBM PC, or what we simply call a PC today. Just like all the platforms of the time, the IBM PC came with a BASIC interpreter, but unlike the others, BASIC wasn't built into the operating system, it was something you had to look for if you wanted to use it. When the PC became the de facto standard, the focus of having end users as programmers started to decline. Magazines stopped coming with BASIC listings for you to type in. When DOS 6.0 came out, PCs even stopped coming with a BASIC interpreter altogether. Now if you wanted to develop software, you had to install a compiler or interpreter yourself, which, sadly, is still the case today.

So I wonder, how do new generations of software developers get their start? It is not as easy to "get your feet wet" these days like it was back in the day. I wonder if they pick computer science without knowing exactly what they are getting into? It's a shame that software development is not as accessible as it once was.


Bookmark and Share
Ensode Technology, LLC

Calendar


BOOKS

Feeds

Search

Links

Navigation