RSS

Tag Archives: java

Is the JVM a viable release platform?

I have written a number of server applications based on Sun’s JVM and luckily for me I have not had to code anything beyond a few interview questions under Oracle’s stewardship. In the last year or so Oracle has released two versions of it’s JVM with well publicized security holes. Normally this sort of thing would go unnoticed or at least pass quietly so what does it mean?

Back in the day when Sun was touting the benefits of Java it was “rewrite once and run anywhere”, “the network is the computer” and security. Whether “security” is defined by phone home, crypto, private and protected modifiers… or the effects of recent attacks you really have to start thinking about Java a little differently.

So when I watched an interview with Rich Hickey this weekend where he talked about Clojure, and by extension Datomic, just plugging into the JVM on your local machine I could not help but get a little concerned. First of all while Clojure is interesting and probably functional and plenty of first-class implementations of things… the hangers on and other libs still use basic JDK libs thus infecting the pure implementation(see that Lift embeds Jetty). And while Clojure is supposed to implement similar read-only features of erlang and other functional languages… what happens when the JVM is attacked sideways?

I like java for what it is and what it might be again. I categorically disagree with some of the language features that are clearly designed for the proprietary sect of this business. And frankly so many more have accomplished much more with less effort using dynamic languages like Ruby, Perl and Python.

One of my strongest beliefs is that in order to scale you need the following: (a) a reasonable ROI on the initial development. (b) ability to automate administration/deployment of the second wave of hardware. (c) ability to automate the automation of the crazy scaling where the application, infrastructure, and people scale organically. At the end of the day scaling must be achieved by applying the lessons of Henry Ford and the assembly line.

 
Leave a comment

Posted by on 2012/09/03 in architecture

 

Tags: , , , , , ,

The Real Three Questions

(1) what do Microsoft, Apple, and Java (in the form of Eclipse, NetBeans and IntelliJ) hope to gain by having such complicated IDEs with so many dependent artifacts?

(2) if all apps were moved to the web, irrespective of the “cloud” attributes will ever be free of the desktop app tools?

(3) most *nix desktop apps appear juvenile or even retro compared to modern Windows and OSX apps; and even some java apps. Will they ever look modern and can they do it without all the cruft required by Microsoft and Apple?

The answers seem obvious to me, however, I’d prefer to hear your response before I give you mine. I thought about giving a hint but that would be too easy.

 
 

Tags: , ,

The next programming language you learn should be GO

I have been asked several times this past week about technologies I would choose to build my next application. There was a time when I adopted Java and the most of the world was still looking at Microsoft’s Visual Studio line of languages.

There was a time when people used to say “no one ever got fired for buying IBM” and more recently this rule was applied to Microsoft.

Java has now displaced COBOL in a lot of mainframe and other big iron installations. While it is stable in many environments it is still encumbered by licensing, deep dependencies, lack of a quality rating system, and is still not available on every platform.

Eventually GO may end up in the same place, however, the current state of the art tools for building and packaging GO application appear to be giving it a leg up. Also since the level of coding is somewhere between C and C++/Java one needs to take an algorithmic approach to software development. With any luck this means more performant code and scaling systems.

Google has deprecated several projects this year and terminated others. This is not always a good thing but clearly they are looking at their ROI as they should. It would be nice if Google would let us know what their commitment for LTS was going to be.

Unlike Java which was closed source for many years after it’s 1.0 release, GO has been open source since it’s beta days. I personally think they are lacking an IDE and a AppEngine toolkit similar to the python version. But for the moment it’s my goto after python.

 
Leave a comment

Posted by on 2012/07/21 in architecture, Tools

 

Tags: ,

Assertions in Java and Go

First and foremost assertions do not exist in Go at all. The language designers had a very specific opinion about it. On the Java side assert was converted to a keyword. This too is interesting and yet maybe not so much.

When servers/daemons are designed in the erlang way where failure is an option then things like assertions are ok. The application will crash, possibly generate a core file, definitely generate a log entry, and then restart. It could be the best of all worlds, especially when you have certain expectations.

Here’s the thing. Unlike the Python and erlang idioms java is strongly typed so it almost makes sense to test input ranges etc and throw exceptions when things go bad. Assertions on the other hand do pretty much the same thing by setting the expectation during development and testing. The idea that the java language designers had was that assertions cost time and space; and if assertions can be removed from production then speed and size are recouped. However, during production you lose the validation that you had during testing and dev. And while TDD etc are supposed to perform exhaustive testing that’s just never the case. Code coverage or not.

If you think I talked myself around in circles just now… I agree. My head is spinning as a result. So here is the bottom line. Forget the keyword. Use the IF statement and generate your own AssertionError. Sadly you won’t win any coding awards for beauty or brevity but you have a chance at consistency and accuracy.

 
Leave a comment

Posted by on 2012/06/22 in architecture, ProgLang

 

Tags: ,

N-way file merge Perl, Python, Go and Lua [Java, Ruby]- Compared

[Update 2012-06-22] Here is the java version of this assignment. It is/was awful. Once you stray from OO, in java, the code inflates like a sea monkey and clearly OO is over the top overkill.

[Update 2012-06-22] Here is the Ruby version of this assignment. I like it’s compactness although that came at a steep price as accessing hash elements meant clunky dereferencing and string comparisons were just awful. [That was an error on my part; works as you'd expect]

Not to beat a dead horse but I now have 4 example implementations in Perl, Python, Go, and Lua.

I did my complaining about Lua in a previous article, however, in summary here… this example in Lua is verbose and lacks consistency. I’m not expecting to reduce this to a single LOC (line of code) but I would have liked some additional APIs that would have implemented more efficient algorithms based on internals knowledge. Or at least well documented idioms.

The Go example was fun because the version 1.x of the toolset was simple to use. I would regularly execute “go run merge_tick_data_hash.go file1.csv file2.csv” and it would run like a champ. The only challenge is/was that simple errors that most dynamic languages permit until the code would actually execute would cause the compiler to barf. And initially I had no idea they were compiler errors; but it was easy enough to get used too. The compiled version of the code was lightening fast to startup and execute even though it was 1.4M bytes in size.

The Perl version took some doing. I was able to reduce the LOC and optimize the code quite a bit. I think there is still some room for improvement based on the Python implementation which was just a few lines smaller because it had the benefit of being written last. In this case I sacrificed adding the filename to the %ticks hash and that reduced a few LOC but added some de-referencing which “might” be optimized by a good JIT; cannot say for certain.

I’d like to compare these implementations to a Ruby version but I’m just not a fan of RVM this week. As for the remaining candidates. I have to admit that I really liked the Go version, however, I do have a complaint that while “Go” seemed like a good name for the project when it started. (prefix for google) right now it’s hard to do google searches. GO is such a small and common word that there is no way to optimize searches. One strong advantage is the static linking once the project is compiled.

 
Leave a comment

Posted by on 2012/06/21 in ProgLang

 

Tags: , , , , ,

Java: everything should be public

If not everything then at least all of the methods and classes.

I wish I new the history of this decision and more importantly what is keeping this artifact of the language in place. I suppose from a historical perspective it has not really caused any trouble. The language designers had some ideas that were rooted in commercial software and commercial software libraries. I’m remembering various commercial JDBC drivers, crypto drivers, X.25 drivers, MQ drivers. But in the modern development environment black box development is no longer the norm; so it might be time to change with the times.

Looking at Ruby, Perl, Python, even Groovy. They are all dynamic languages. They are all compiled or processed at runtime and so there is no benefit to private or protected objects. The code is there for the reading if you are so inclined. Java and C++ are compiled languages. Java does have some capability for runtime meta programming. But while historically developers purchased libraries to supplement the core JDK, they are now using Maven repositories like Ruby’s Gems, Python’s PyPi, and Perl’s CPAN.

private and protected are now more for vanity than any “protection” that the Java’s creators had envisioned.

 
Leave a comment

Posted by on 2012/05/09 in ProgLang

 

Tags: , , , , , , , , ,

Getters and setters are STILL evil!

I’m a 3rd party reading the source code of another 3rd party for a project I’m working on and I find my head spinning because the Class that I’m currently reading is 90% getters and setters. Of course I did a little googling in order to see what the current state of accessors was and that’s when I found this evil article. Looking at the byline I think it was written in 2003 and of course not much has changed since then.

What troubles me about the article is that it nor any of the OO gurus ever discuss anything but the simplest OO objects like point, line, square, circle. Sure, when you have essentially 3 or 5 input values it’s simple to accept them in the constructor. But when you have 100 instance values of varying types then what? In the evil case getters and setters are used so that the data is validated during the set based not he rules of the class declaration. Using a single get/set does not give you that functionality and validating in the constructor makes the class unwieldy.

With so many getters and setters there is so much static code that would need to be hand coded and the only shortcut would be calling the getters and setters with some reflection. Unfortunately that has other side effects when combining meta programming and OO.

Personally I like the python approach of typeless data. Then I wrap the instance data in a hash called a dict in python. And then if I really need to validate the data it’s either done when the data enters or exits the system (using a userspace data type dict) or when constrained in the data store (DB).

I’m just not a fan of the getter/setter. Too much code. Too little payback.

 
Leave a comment

Posted by on 2012/02/14 in ProgLang

 

Tags: , , , ,

CRUD-fest : grails, rails, django shootout

The mission is to deploy a CRUD implementation in all three frameworks by reverse engineering my schema from an existing Postgres Database which I will construct with raw SQL. Later I would like to add some data to the tables so let’s see how it handles some ETL (export transform load) in the form of a CSV file into some REST calls that I’d implement or some other type of messaging.

What I did not do! I think O’Reilly has the most comprehensive map of the history of all computer programming languages, however, GitHub has a list of languages that would seem to be current or relevant. Granted that some of this, to be effective, would mean investigating popular frameworks within the domain of languages. Well of that semi-complete list from GitHub I picked out this set: php, go, lua, haskell, erlang, scala, clojure, perl, javascript, rhino, nodejs, iOS, Objective-C, C++, C, Pascal, Pro-SQL, CoffeeScript, OCaml, Scheme, tcl, Smalltalk, Visual Basic. I think they are the most relevant. As it goes, however, either they do not reverse engineer schema from a PG (postgres) connection like most ORMs, or they do not have web or other application frameworks in order for a user to interact with the data, and many do not have IDEs or version managers they way that Ruby and Python do. (I cover the IDE topic later.) I think I picked the sweetspot of frameworks to test and skipped the ones that would distract me from the task.

Code Wars: PHP vs Ruby vs Python – Who Reigns Supreme [Infographic]

Let’s start with the schema design. The actual SQL is here. The “message” represents an ISO8583 message. You can follow the link to read more about the message. What’s important to know is that it represents the standard message used between certified credit card acquirers and their associations like Visa, MasterCard, Amex, Discover and many others.  It also represents the message used between the associations and their issuing processors. The message format is also reused by many POS terminal software vendors as well as gateway and technical acquirers/processors. Each association has slightly different implementations depending on their specific needs, however, most of the fields have common names and usage.

When building an endpoint or a gateway or any point in between there is a need to support ISO8583 and a bigger need to test the endpoint. As part of the testing phase it’s important to build a test harness that can generate the necessary test transactions. Depending the application’s position in the network it will have different testing needs. One thing for certain is that the messages and their contents need to be modeled, testable and repeatable. One huge challenge is TDD (test driven development) and another is simple regression testing. It’s my personal belief that a well defined toolset could be deployed in such a way that vendors across the board could contribute data a code for regression testing thus reducing the load on everyone. PS: while this mission is ISO8583 there is no reason why a request/response transaction could not be JSON, XML or S-exp; it’s a general enough schema.

  • TABLE: message_field_dictionary – this is a list of the field names and their formats. Nothing else.
    • FIELD: id (PK)
    • FIELD: field_id (FK)
    • FIELD: field_name
    • FIELD: field_description
    • FIELD: field_format (i.e.; ‘YYYYMMDD’)
    • FIELD: data_types (a, an, ans)
    • FIELD: default_values (i.e.; ’1′, ’2′, ’3′, ‘abc’…)
  • TABLE: message_request – this is the set of fields used in a particular request transaction. It is also possible that this represents the incoming request pattern. If the pattern does not match then that’s separate issue.
    • FIELD: id (PK)
    • FIELD: test_case_id (FK)
    • FIELD: field_id
    • FIELD: request_type
    • FIELD: field_value
  • TABLE: message_response – this is a set of fields in the response generated from the response. This might also represent a response message based on the incoming request pattern.
    • FIELD: id (PK)
    • FIELD: test_case_id (FK)
    • FIELD: field_id
    • FIELD: response_type (i.e.; absent, required, optional, conditional)
    • FIELD: field_value (i.e.; a value, regex, or a combination set, private function or other field_id)
  • TABLE: message_test_cases
    • FIELD: id (PK)
    • FIELD: test_case_id (FK)
    • FIELD: short_name (FK)
    • FIELD: description
    • FIELD: expected_results
    • FIELD: elapsed_ceiling
    • FIELD: is_active
    • FIELD: group_name
    • FIELD: sub_group_name
  • TABLE: message_test_results
    • FIELD: id (PK)
    • FIELD: test_case_id
    • FIELD: started
    • FIELD: finished
    • FIELD: elapsed_time
    • FIELD: results
    • FIELD: request
    • FIELD: response
    • FIELD: errors
    • FIELD: trace
  • TABLE: test_cards – I decided to put the test cards in a separate table because if contributors provided test transactions the actual card numbers and magstripes would be considered confidential data… and the associations do not want anyone recording that info with one possible exception.
    • FIELD: id – (PK)
    • FIELD: card_number (FK)
    • FIELD: serial_number (FK)
    • FIELD: expiration_date
    • FIELD: issue_date
    • FIELD: street
    • FIELD: zipcode
    • FIELD: pin
    • FIELD: atm_pin
    • FIELD: CVV
    • FIELD: CVV2
    • FIELD: track1
    • FIELD: track2
    • FIELD: track3
    • FIELD: reset_balance
    • FIELD: is_decrement
    • FIELD: actual_balance
    • FIELD: open_to_buy

The schema is self explanatory. I did not create any real indexes. I’m not certain (right now) whether I’m going to create any FKs or referential integrity. It depends on how much reverse engineering the different frameworks are going to execute. One thing for sure, this is not intended to be a lesson in DB design. Maybe another time. FKs might be required in order for the reverse engineering to work properly. Specially if I use tables to populate pulldowns and select lists.

The IDE I decided to use was RubyMine, PyCharm and IntelliJ. It is purely by coincidence that I decided to use this family of IDE from jetbrains. (for the record I’m currently using the demo version. I’m hoping that the licenses do not expire before I finish this article… this paragraph was written before coding began). What makes them interesting is that they support Django, Rails and Grails out of the box. After agonizing over it IntelliJ was the only reason why I included Grails. Java does not have a version manager like Ruby or Python, however, you can get there by collecting your jar files in a single folder alongside the JDK you’re using. And since many binary distributions of the JDK are in version folders it makes resetting the CLASSPATH and PATH easier… but still more manual than the ruby and python versions.

RubyMine heads up. When I originally installed RubyMine I had not installed RVM. I found a post from the folks at JetBrains about version 2.0.2 where they probably added RVM support. Anyway they said it just worked. That after a restart RubyMine would give you access to your tools. That was not the case. I had to take one extra step. I had to go into the preferences and navigate through the “Ruby and SDK” page. I also navigated through the gem sets for good measure. Now when I created my project I had access to my Rails version; previously unknown. I had a similar problem with PyCharm and it’s support for VirtualEnv but I will have to verify it with Django. (Shame on me. My desktop virtualenv did not have django installed. I will likely have to do a complete install based on my notes which were originally installed on my virtual machine and not my desktop).

Getting Started

Now that I’ve managed to crawl through the minutia of project preparation it’s time to start putting the project together. So Now that I have installed IntelliJ, PyCharm and RubyMine I have to create my project. I’m calling the project crud_fest_rb, crud_fest_py, and crud_fest_j.

Creating an empty rails and an empty django project was pretty simple. Specially after all the setup I’ve done in preparation. The one observation I’ll make is that there are a lot more artifacts in an empty rails project than there are in a similar django project. The Grails project has a lot more artifacts than that and since there is a compilation step it takes a lot longer to get started. One thing that bugs me about IntelliJ is that it starts the browser to a default page once it’s ready to run.

This project was not meant to be a JetBrains tutorial, however, I’ll mention a few more things. Rails started right away. Django required the user to enable the admin function, update the settings file to point to the proper DB, and then you had to manually execute the ‘manage.py syncdb’ command in order to create a default admin  user. This step will be required later in order to sync the db schema to the model. Rails and Grails are still under investigation.

One nice thing about the Rails and Django projects is that they respect SQLite3. Not that Grails goes out of it’s way to reject SQLite3 but the support is hard to come by. This means that when I put my SQL together it will need to support but SQLite3 and H2. Which will probably work but what a pain. I suppose I could use Postgres but there is nothing easier than a ‘cp’ command to reset the DB to it’s default. And if this project is successful then copying the output table to the target application means that that the SQLite DB file is now the config file.

The Schema

I have created the SQL. I was not going to embed the code directly but the Gist is here. It’s only six small tables and the foreign keys are few. There are a few constraints which should be removed when the constraints are fully represented in code instead of schema. (Keep in mind that when calculating performance things like O(log<n>) no longer makes sense when there are cascading reads based on constraints. And frankly it does not make any sense to have the constraint modeled in code and SQL at the same time.)

Import the Schema

… into the project is the next step.

Django

PyCharm could execute the following commands but currently it feels better to execute them manually from the command line.

The first step is making sure that the DBs are configured properly in the settings.py file. In a recent version of Django the developers made it possible and easy to support multiple and different databases simultaneously. That means I could connect to one DB for one set of actions and another DB for a different set. There are plenty of interesting use-cases here. So let’s configure the DB:

DATABASES = {
 'default': {
     'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
     'NAME': '/tmp/crud_fest.db', # Or path to database file if using sqlite3.
     'USER': '', # Not used with sqlite3.
     'PASSWORD': '', # Not used with sqlite3.
     'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
     'PORT': '', # Set to empty string for default. Not used with sqlite3.
 },
 'messages': {
     'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
     'NAME': '/tmp/crud_fest_py.db', # Or path to database file if using sqlite3.
     'USER': '', # Not used with sqlite3.
     'PASSWORD': '', # Not used with sqlite3.
     'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
     'PORT': '', # Set to empty string for default. Not used with sqlite3.
 }
}

(The indenting is not exact here but that’s a WordPress thing)

The second step is to make certain that the admin functionality that we previous enabled (and now stored in the default database: crud_fest.db) has been sync’d properly. (you’ll need to answer some questions about the admin user including the username and password.)

/Users/rbucker/git/flafreeit/crud_fest_py/manage.py syncdb

Now that the admin tables have been created, you’ll need to create the actual crud_fest_py tables.

cd ${HOME}/git/flafreeit/crud_fest_db
sqlite3 /tmp/crud_fest_py.db <./setup.sql

And then the last step is to dump or reverse engineer the table(s) into a models.py file.

/Users/rbucker/git/flafreeit/crud_fest_py/manage.py inspectdb > /Users/rbucker/git/flafreeit/crud_fest_py/test_config/models.py

Looking at the models.py file you’ll see something like (looks like I have some trimming to do; the admin tables were included):

# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# Feel free to rename the models, but don't rename db_table values or field names.
#
# Also note: You'll have to insert the output of 'django-admin.py sqlcustom [appname]'
# into your database.
from django.db import models
class MessageFieldDictionary(models.Model):
    id = models.IntegerField(null=True, primary_key=True, blank=True)
    field_id = models.IntegerField(unique=True, null=True, blank=True)
    field_name = models.CharField(unique=True, max_length=25, blank=True)
    field_description = models.TextField(blank=True)
    field_format = models.CharField(max_length=200, blank=True)
    data_types = models.CharField(max_length=200, blank=True)
    default_values = models.CharField(max_length=200, blank=True)
    class Meta:
        db_table = u'message_field_dictionary'

This is just a sample of the tables that inspectdb generated… because there is one final step. Now that we have a models.py file with the individual schema we need to tell Django about the tables and the individual fields that need to be editable. There are some shortcuts; the online docs are really good. So we are going to create an admin.py file like this.

from django.contrib import admin
from myproject.myapp.models import MessageFieldDictionary

class MessageFieldDictionaryAdmin(admin.ModelAdmin):
    pass
admin.site.register(MessageFieldDictionary, MessageFieldDictionaryAdmin)

Once this last step is completed then you need to launch the django server and navigate to the admin site with your favorite browser. All of your tables should be there. You might still need to customize the widgets but this is the place where we stop.

One Final note. Sadly my decision to use SQLite means that I might have to do all of this all over again. It seems that the foreign keys have not been incorporated into the results of the ‘inspectdb’ command. There is a pragme in SQLite that enables FKs but it has to be compiled in beforehand. There was also at least one multi field constraint that does not appear.

But this is a good place to stop for now.

Rails

The first thing I noticed is that there is no code in Rails for reverse engineering a legacy database the way that Django does. So I had to install a missing gem.

gem install rmre

Then I had to reverse engineer my DB.

cd ${HOME}/git/flafreeit/crud_fest_rb
rmre -d /tmp/crud_fest_py.db -o ./app/models/

After the command completed I was returned to the command line. There were no error messages so I assume that it completed OK. I looked in the ./app/models/ directory and noticed that there were a handful of new files. These files were 1:1 with the table names. Here’s an example:

class MessageFieldDictionary < ActiveRecord::Base
    set_table_name 'message_field_dictionary'
end

This is a little hinky because none of the field names or types have been included. After doing some searching I found that this is OK and that ActiveRecord will fill in the blanks. I don’t know if I buy that. I like that Django fills in the holes and this sparse programming … *sigh*.

There is another command that is interesting:

rake db:schema:dump

This will dump the schema into a file db/schema.rb. It represents the complete schema. I suppose that this code could be copied to the model files. But for the moment this is not required… I think the db:migrate command will regenerate this db/schema.rb file when it completes.

Another caveat here is that it is possible to have multiple databases configured in the database.yml file. The difference, however, is that ActiveRecord needs to know which database goes with which definition. So there is some manual work to be done here. There are some simple google searches you can execute and most of them make perfect sense. It’s a little beyond the scope here even though I described the python version.

Grails

Grails supports multiple databases in it’s DataSource.groovy file. Since I’m working with Grails 2.0.0 there is a possibility that the latest Hibernate is included. Hibernate is the ORM that Grails uses to communicate with the DB. But the tool for reverse engineering needs to be installed.

cd ${HOME}/git/flafreeit/crud_fest_j
grails install-plugin db-reverse-engineer

The output was pretty simple.

rbucker@rmac[crud_fest_j]$ grails install-plugin db-reverse-engineer
| Plugin installed.

… but I have no idea which version was installed. So we move forward for the moment. The next step is to locate the h2 command line version.

java -cp ${HOME}/lib/grails-2.0.0/lib/com.h2database/h2/jars/h2-1.2.147.jar org.h2.tools.Shell

You’ll need to answer a few default questions. You can accept the default values for the moment.

Now that H2 is running and pointing to the same repository as the DataSource.groovy, now we need to run the SQL to create the database tables as we did previously. (I had to make some changes to the code because there are some differences with H2.

Now we try to do the reverse engineering…. actually, it’s not going to happen. I’m going to leave this up to the reader to complete. And if anyone wants to contribute, please, by all means. For the moment This is the end of the road for this project.

Conclusion

It is safe to say that I’m done with this project. While it seems plausible that I could reverse engineer a database using the Grails Plugin – the amount of configuration required just amazes me. Spring is heavily dependent on XML config files and it appears that Grails uses some of each. One thing for certain is that Java has these huge namespaces everywhere so just the slights config requirement for reverse engineering is so incredibly painful. I’m really surprised that the Grails guys did not do more Groovy scripting for this sort of thing.

Ruby/Rails on the other hand still required an outside GEM in order to perform the reverse engineering. I’m surprised that with Rails3 and 3.2 that they never addressed the issue directly. And not to mention that the resulting models were still sparsely emitted.

Finally, Django seems to have gotten it right. It emits the code in it’s entirety. Getting to the CRUD is a simple matter of some manual labor which the user could script easy enough. My vote is going to Python as the all around winner and Ruby a close second. The Java code is on hold, maybe we can call this a “did not finish”. The overall performance of the dependencies and the compile step make it a less valuable experience.And let’s not forget the JDK version madness.

So for the time being I’m inclined to purchase a license for PyCharm and RubyMine just because this is where I’m going to be spending my time for a little while… and it’s my money.

 
 

Tags: , , , , , ,

Netty 3.3.0 was release with some dependencies

I’d like to try some netty code whether it’s standalone or connected to Apache:Camel but when I downloaded the source I saw that I needed Maven2 in order to build it. So I started the install process for Maven2…

Yikes! I have no idea what licensing constraints I’ve entered into; why maven needs rhino and a large number of other libs.

Back in the day when Object Oriented programing was becoming popular, around 1983-ish, people gravitated to the private/protected/public guarding of methods and data. I’m not sure why that was but I can guess it’s probably ego. There was a point to it when code or libraries were distributed in binary only form but today open source has all but eliminated secret sauce and we typically use naming to identify usage with documented examples and recommendation.

That said, the super-dumptruck needs to be replaced with a backpack approach. This means that there is a more granular approach to installing dependencies and even interdependencies but it 2012 and we should be able to handle this.

rbucker@soldev:~/src/netty-3.3.0.Final$ sudo apt-get install maven2
Reading package lists... Done
Building dependency tree 
Reading state information... Done
The following extra packages will be installed:
 antlr bsh bsh-gcj fop gcj-4.6-base gcj-4.6-jre-lib java-wrappers libantlr-java libasm3-java libavalon-framework-java libbackport-util-concurrent-java libbatik-java
 libbsf-java libclassworlds-java libcommons-beanutils-java libcommons-cli-java libcommons-codec-java libcommons-collections-java libcommons-collections3-java
 libcommons-configuration-java libcommons-digester-java libcommons-httpclient-java libcommons-io-java libcommons-jxpath-java libcommons-lang-java
 libcommons-logging-java libcommons-net2-java libcommons-validator-java libdoxia-java libdoxia-sitetools-java libexcalibur-logkit-java libganymed-ssh2-java libgcj-bc
 libgcj-common libgcj12 libgeronimo-jms-1.1-spec-java libgnuinet-java libgnujaf-java libgnumail-java libgoogle-collections-java libitext1-java libjdom1-java
 libjline-java libjsch-java libjsr305-java libjtidy-java liblog4j1.2-java libmaven-archiver-java libmaven-clean-plugin-java libmaven-compiler-plugin-java
 libmaven-dependency-tree-java libmaven-file-management-java libmaven-filtering-java libmaven-install-plugin-java libmaven-jar-plugin-java libmaven-plugin-tools-java
 libmaven-reporting-impl-java libmaven-resources-plugin-java libmaven-scm-java libmaven-shade-plugin-java libmaven-shared-io-java libmaven2-core-java libmodello-java
 libnekohtml-java libnetbeans-cvsclient-java liboro-java libplexus-ant-factory-java libplexus-archiver-java libplexus-bsh-factory-java libplexus-build-api-java
 libplexus-cipher-java libplexus-classworlds-java libplexus-compiler-api-java libplexus-compiler-javac-java libplexus-compiler-manager-java
 libplexus-component-api-java libplexus-container-default-java libplexus-containers-java libplexus-digest-java libplexus-i18n-java libplexus-interactivity-api-java
 libplexus-interpolation-java libplexus-io-java libplexus-sec-dispatcher-java libplexus-utils-java libplexus-velocity-java libqdox-java libregexp-java librhino-java
 libsaxon-java libservlet2.4-java libservlet2.5-java libslf4j-java libwagon-java libwerken.xpath-java libxalan2-java libxbean-java libxml-commons-external-java
 libxmlgraphics-commons-java libxp6 rhino velocity
Suggested packages:
 bsh-doc fop-doc libantlr-java-gcj libavalon-framework-java-doc libbackport-util-concurrent-java-doc jython libclassworlds-java-doc libcommons-beanutils-java-doc
 libcommons-collections-java-doc libcommons-collections3-java-doc java-virtual-machine libcommons-digester-java-doc libcommons-httpclient-java-doc
 libcommons-io-java-doc libcommons-jxpath-java-doc libcommons-logging-java-doc libcommons-net-java-doc libdoxia-java-doc libgcj12-dbg libgcj12-awt libgnumail-java-doc
 libjline-java-doc libjsr305-java-doc libjtidy-java-doc liblog4j1.2-java-gcj libmx4j-java libmodello-java-doc libnekohtml-java-doc libplexus-classworlds-java-doc
 libplexus-component-api-java-doc libplexus-container-default-java-doc libplexus-i18n-java-doc libplexus-interactivity-api-java-doc libplexus-utils-java-doc
 libplexus-velocity-java-doc libqdox-java-doc libsaxon-java-doc libservlet2.4-java-gcj libjavassist-java libwagon-java-doc libxalan2-java-doc libxsltc-java
 libxalan2-java-gcj groovy libspring-core-java libspring-beans-java libspring-context-java libspring-web-java libequinox-osgi-java librhino-java-doc velocity-doc
The following NEW packages will be installed:
 antlr bsh bsh-gcj fop gcj-4.6-base gcj-4.6-jre-lib java-wrappers libantlr-java libasm3-java libavalon-framework-java libbackport-util-concurrent-java libbatik-java
 libbsf-java libclassworlds-java libcommons-beanutils-java libcommons-cli-java libcommons-codec-java libcommons-collections-java libcommons-collections3-java
 libcommons-configuration-java libcommons-digester-java libcommons-httpclient-java libcommons-io-java libcommons-jxpath-java libcommons-lang-java
 libcommons-logging-java libcommons-net2-java libcommons-validator-java libdoxia-java libdoxia-sitetools-java libexcalibur-logkit-java libganymed-ssh2-java libgcj-bc
 libgcj-common libgcj12 libgeronimo-jms-1.1-spec-java libgnuinet-java libgnujaf-java libgnumail-java libgoogle-collections-java libitext1-java libjdom1-java
 libjline-java libjsch-java libjsr305-java libjtidy-java liblog4j1.2-java libmaven-archiver-java libmaven-clean-plugin-java libmaven-compiler-plugin-java
 libmaven-dependency-tree-java libmaven-file-management-java libmaven-filtering-java libmaven-install-plugin-java libmaven-jar-plugin-java libmaven-plugin-tools-java
 libmaven-reporting-impl-java libmaven-resources-plugin-java libmaven-scm-java libmaven-shade-plugin-java libmaven-shared-io-java libmaven2-core-java libmodello-java
 libnekohtml-java libnetbeans-cvsclient-java liboro-java libplexus-ant-factory-java libplexus-archiver-java libplexus-bsh-factory-java libplexus-build-api-java
 libplexus-cipher-java libplexus-classworlds-java libplexus-compiler-api-java libplexus-compiler-javac-java libplexus-compiler-manager-java
 libplexus-component-api-java libplexus-container-default-java libplexus-containers-java libplexus-digest-java libplexus-i18n-java libplexus-interactivity-api-java
 libplexus-interpolation-java libplexus-io-java libplexus-sec-dispatcher-java libplexus-utils-java libplexus-velocity-java libqdox-java libregexp-java librhino-java
 libsaxon-java libservlet2.4-java libservlet2.5-java libslf4j-java libwagon-java libwerken.xpath-java libxalan2-java libxbean-java libxml-commons-external-java
 libxmlgraphics-commons-java libxp6 maven2 rhino velocity
0 upgraded, 103 newly installed, 0 to remove and 1 not upgraded.
Need to get 60.3 MB of archives.
After this operation, 134 MB of additional disk space will be used.
Do you want to continue [Y/n]?

Now that I installed Maven2 I performed a ‘mvn clean’ command. Maven is now downloading countless artifacts from the maven server. (I’m not going to copy all of the filenames here)

In conclusion… there is no way that a single person can manage a project with this dependency stack unless you a) don’t care about full stack awareness; b) just going to defer all responsibility future generations; c) have a crystal ball that points out bugs and provides magic workarounds.

 

Tags: , , , ,

Clojure and Scala… again

[Update 2011-08-09: I am returning from a failure to install scala and clojure. I was able to install OpenJDK from the Ubuntu packages, however, I wanted to build ant from source. And that does not appear to be possible. Ant depends on JUnit and JUnit depends on Ant. This makes it impossible to install everything from source. What's worse is that the build instructions are so much worse than I remember. There was a time when I would install all my Java tools except the JDK and my commercial JDBC drivers by hand.]

I just watched a video presentation from one of the Twitter geeks and he was going on and on about the JVM. What make it interesting is that Twitter is moving from Ruby to the JVM, in fact everything is now written in Java or Scala; and there are some research projects in Clojure.

I was looking over my resume recently as I was reviewing my Java experience for a potential position. And with about 10 practical years experience from the first version of Java (1.02) until a few years ago… it was an uphill battle with most managers. Now “Java is the new Cobol” or “nobody ever got fired for using Java”.

I find myself looking back at dynamic languages with a little more interest. Perl and I have a long history and Python and I are getting there.

But I have some criticisms:

  • Eclipse was a wonderful project once. Now it’s total chaos.
  • NetBeans is a nice platform but with a little FUD I’m concerned about Oracle and eating your own dog food. We might not be getting the best tools from them.
  • There are other Java IDEs but they are expensive or single purpose. (IntelliJ’s Idea is $199 for an individual license; but it supports Groovy, Clojure, and Scala.)
  • I tried to install Scala and Clojure using packages, however, the version numbers were so far back that it’s scary. I have heard “please upgrade” too many times.

On the positive side I have a couple of books already. I’m sure they are good enough. I’m still a little bitter about the dependency on Java libs for Scala and Clojure but if you’re a functional programmer I think that Scala and Clojure are going to be easier to sell than Erlang or Haskell… as they are incremental steps (baby steps) and they still use the JVM.

So what is the plan or roadmap?

  • deploy jars and wars
  • instrument deliverables in a consistant way
  • use event driven design with MQs
  • watch your TPS rates in terms of events
  • log in a way that makes sense
  • plan to deploy in a cluster (see MQ)
  • plan to use 3 types of databases (OLTP, OLAP, DW)
  • use one-way replication in a rollup fashion
  • Keep it simple by making sure that the unit of work is something the average programmer can pick up.
  • Stay native. If you’re writing a Scala app then use Scala libs. And when you cannot, write it yourself. And when that’s not possible then use a Java version; and plan to write it when you can.

Scala and Clojure are going to get another shot real soon.

PS: and so I’ll probably launch a jar framework for application monitoring. Anyone want to play?

 
2 Comments

Posted by on 2011/08/09 in beta, ProgLang

 

Tags: , , , ,

 
One Page Docs

Creating a library one page at a time.

One Page Bugs

Reducing the friction of writing and fixing bugs or features.

Follow

Get every new post delivered to your Inbox.

Join 223 other followers