Archive for the ‘technical’ Category

explain this

Monday, August 13th, 2007

type parameters of T cannot be determined; no unique maximal instance exists for type variable T with upper bounds T,java.lang.Object

In java 1.6u2 running in maven 2.0.7, we started getting this message but in eclipse 3.3.0 we were not. (and in idea we also were failing)

First, what the hell does this message means? Second, why can eclipse handle the issue and not the regular jdk?

Anyhow the problem was caused by this (our example was a little more complex than this):

public <T> T getFoo() {
T result;
result = getBar();
return result;
}

public <T> T getBar() {
return (T) map.get(”bar”);
}

The workaround is casting the line:

result = getBar();


to:

result = (T)getBar();

sun should get into the hosting business

Monday, July 30th, 2007

Sun keeps trying to offer Sun essentials for startups to Amplafi. The problem is that we don’t want to purchase services at the box level. We want to purchase at the java vm level. Buying a box means we have to worry about maintaining it. But that is the level that Sun is used to talking at and selling at.

We are agnostic out of necessity to questions about os, hardware, etc…. so Sun needs to go further up the foodchain for Sun to be able to sell to Amplafi.

Sun should stop being afraid of pissing of partners and start experimenting with offering their own hosting service at the java vm only level. After all who can manage Sun boxes and Sun’s java vm better - Amplafi, JoeBlow’s hosting service or the people who wrote the vm and built the box?

Notes from the “End of Software”

Thursday, June 28th, 2007

So this evening, I got to dine on some very nice flesh courtesy of Callidus Software. They sponsored Tim C.K. Chou talking about the “End of Software”, otherwise known as Software as a Service (SaaS).

Interesting talk, confirming what I have thought for a long time and something that Salesforce is making millions on… installed software is costly to maintain. But the funny thing is that Tim missed one of the key reasons why installed software sucks and costs so much -vendor indifference!

I used to work at (nameless), which sells enterprise software.. For the longest time, (nameless) was in the business of big installations, long roll-outs, long sales cycles. Of course they had long training classes where legions of people (who had no say in the original decision to purchase (nameless)’s solution) were compelled to remember the cryptic commands and button clicks that would insure they would be able to continue to do their job. These people dread the next release of the software because invariably the magic would change and they would be thrust back into a world where they were worse off than before (nameless) was introduced and their quarterly bonus that much further out of reach. Of course the source of the pain was the software engineers toiling away thinking of nothing more than ‘improving’ the software.

When I asked about just making the software more usuable and more obvious… here was a sample answer:

Well we colored the buttons yellow to make our product easier to use.

(pause for the screaming)

So anyhow when (nameless) decided to shift to the SaaS model, all of a sudden they discovered and felt directly the pain only the customers felt before. Now (nameless) was at least incensed to make the software easier to install. Time will tell if they move beyond yellow buttons.

So back to the talk. Tim talked about the reason he rejoined Oracle (and he admits that at first he didn’t see the value of SaaS), but it was to help create Oracle’s SaaS solution.

Security
One of the first key question Oracle faced was that of security. But this is interesting, which company is better about securing their Oracle databases: Oracle or some random paper company — obviously Oracle. But also there is some data that is more secure outside the company than inside. For example, salary and HR data. A company’s DBAs have access to every employee’s salary if that information is hosted internally. However, if the data is hosted by Oracle then the vulnerability to internal hackery is gone.

Cost
People don’t have a good idea of the cost of software. According to Tim the cost of maintaining the software is between 70-80% of the total IT budget. In some companies the IT budget is completely devoted to just maintaining the existing software.

Oracle found that 4x-8x the cost of the original “price” of software is spent per year to maintain the software system. This means that if the software cost $1million. Maintenance costs were $4million/year so with in 5 years the true cost of the software was $21million. Apparently ‘free’ software has just resulted in increasing the multiplier, but there is still real and significant costs.

So what is the source of these costs: patches, backups, hardware upgrades, os upgrades, hard disk crashes, configuration management software, etc. But the other reason for the cost is that each system at a customer site is different than the one next to it. The OS is at a different rev, the hardware is newer, older, or from a different manufacturer. These differences mean that nothing is ’standard’. This non-standardization means that opportunities to use automation to reduce costs are few…. and the quality of the result is low. Now as a fan of the agile programing model — I loved the next statement “High quality = low costs, low quality = high costs”….

SaaS steps in
SaaS is all about standardization, repetition and automation — at a level beyond that of which an individual company can achieve.

Three interesting things about SaaS: Specialization, Games matter, Knowledge is king.

Specialization
SaaS is all about heavy degrees of specialization. The service does one thing and does it well. Ostrich farming software or search (google) — SaaS means that many of the mechanics of getting the utility of the software (notice — not the bit of code themselves) disappear. If ostrichfarming.com is based in Australia - they can still offer value to the ostrich farmer in Russia or Colorado.

Specialized providers know the market - the generalists don’t.

Games matter
In World of Warcraft, a player can see if the other character is a mage or a fighter, their race, and in general there ability. But most importantly, in WoW, teams of various skills interests, language, and abilities from all over the world come together to achieve a goal and then they go away. In WoW this happens automatically and all the time. SaaS and game theory are very similar in this regard. WoW has a currency-based system, SaaS-based business such as seriosity are exploring applying this to business problems.

Service matters and information means better service
Amazon is arguable able to offer better service than the corner bookstore because Amazon can answer the questions: “What do other people think of this book?” and “Will I personally like it?” So this is the next step beyond SaaS. No longer is the question about what feature to add, but now people are interested in the question “Which sales compensation plan works best?”

Interesting stat: Google/Yahoo see 100 terabytes of data in the visible web. 100,000 terabytes of hard drive storage was sold last quarter alone.

Interesting afterwords: Shanker Trivedi of Callidus (SVP Marketing) said one of the biggest issues they face is educationing the customer on the value of the service they can offer. This says to me that the value of SaaS is still being realized and there is a long way to go for the average non-geek executive to really realize the impact and potential. I also suspect there will be more turmoil in the IT ranks as more and more software isn’t sold as such but offered as a service. SaaS lets customers really see the value of the solution they are buying not just a blizzard of marketing promises.

Thoughts on how to evaluate code

Tuesday, May 29th, 2007

I met someone at Startup Camp2 who was non-techincal but had an idea that required technical expertise.

She faced the typical problem of judging and evaluate software code in order to make sure the people she hired were:

  • competent
  • making progress

This is of course hard especially in the beginnings of a project when so much is really building infrastructure code and configurations, none of which involves ‘visible’ progress.

I whipped off a quick email in response that even after sleep I still rather like:

  • Maintainability
  • Performance

These are your 2 key metrics. Poorly written code fails in these two areas.

Maintainability


Commented Code

Look through the code. Do all large methods have well-written comments that *you* can understand. You may not understand all the details but if there are no comments or the English is poor, this is bad. Any other developer coming later is going to have a hard time understanding what the original developer was trying to do and will probably create bugs when adding new features.

Key point: The comment should talk about *why* not just *what* is being done. The developer must describe all convoluted (to you) code in a *written* comment. This comment should be understandable to you, the layperson, to a reasonable degree. Chances are very good that, if he/she cannot that:

  • He is not quite certain himself what it does
  • He probably has not thought through completely all the issues around this code.
  • It has lots of bugs.

Be careful not to get lost in the weeds here. Have the developer take you through the high-level code, not the low-level stuff. Low-level stuff will distract you from seeing the bigger picture. You may want a friend developer who knows the language in question but be prepared to be able to fly solo on this after a few reviews.

Sample comment:
/**
 * Application State Object that tracks the current state of a flow. Holds any
 * state information related to a specific flow
 *
 * Each flow state has all the information to run the flow and re-enter it if
 * needed.
 *
 * defines an actively executing flow. Each FlowState has an attached
 * Flow which is the instantiated definition. This copy is made to avoid
 * problems with flow definitions changing while an instance of a flow is
 * active.
 */

Integration Tests/Unit Tests:

These are automated tests that anyone can run from the command line ( i.e. should not require bringing up a development environment.) You should be able to run a command line tool that reports number of tests run and the code coverage of those tests. These tests should include running something like selenium that will bring up a browser and run through your site.

Packaging

You should have a set of clear step by step instructions to get from a brand new machine to running the tests to bringing up the service. You need to be able to verify this yourself. Using only the directions only as written i.e. *no help from anyone* can you get the machine set up, source code downloaded from a source code repository**, compiled, and running? You should be able to type ‘http://localhost/’ and see your website.

[**Run away from any developer that doesn't understand source code repositories. They are your insurance that 3 months into development the developer's machine crashes and everything is gone.]

Can you bring up the development environment and start the product following the written directions by yourself? This avoids the possibility/probability that the developer’s machine is magically configured and only his machine is set up just so to build the product. Believe it or not, I have worked at large companies that are hair-pulling experiences because everything has to be magically configured to build the product.

Performance


How many people are going to hit your web server? What is the peak load going to be? What kind of response is the developer giving about issues like scalability?

Big issue here. Have the developer create jmeter tests that show how the server behaves under load. When running a jmeter test look at memory usage and CPU % on the server and that database. Ratchet up the number of jmeter users until the service just dies. Is that number acceptable? Look into making the service scalable using Amazon’s ec2 service. Ask questions about how much memory each logged in user takes. If each logged in user takes 1 megabyte of memory, you will only be able to have 300 or so users at a time/machine!

Any developer worth anything knows to use a database and well but they are not experts. Spend the money for a day or two of a database expert’s time. Have them take a look at the queries your service runs against the database. Have he/she do at least a little bit of tuning (this will be on-going process) but could easily allow the service to run 10x - 100x better.

apache v. tomcat mysteries…

Tuesday, May 29th, 2007

So I struggled for hours trying to get apache to connect via the ajp13 worker to tomcat 5.5 We are using a Debian box on the production server. Could not make it happen…. until I set the worker to be ‘ajp13′.

Don’t understand what wierdness is going on but… I do know this. if my /etc/libapache-mod-jk/workers.properties file looks like this (comments removed):

workers.tomcat_home=/usr/share/tomcat5.5
workers.java_home=/usr/local/java
worker.list=ajp13
worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
worker.ajp13.lbfactor=1
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=ajp13

Apache 2 talks very nicely with Tomcat 5.5.20

If it looks like this:

workers.tomcat_home=/usr/share/tomcat5.5
workers.java_home=/usr/local/java
worker.list=amplafi_ajp13
worker.amplafi_ajp13.port=8009
worker.amplafi_ajp13.host=localhost
worker.amplafi_ajp13.type=ajp13
worker.amplafi_ajp13.lbfactor=1
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=amplafi_ajp13

Everything is broken!

Does anyone have a clue here on why?

What the hell were they thinking?

Tuesday, May 1st, 2007

I ran across this article about IE’s ‘wonderful’ MIME sniffing. Take a look at this report. Apparently, Internet Explorer looks at the first 256 characters of the file requested. If IE thinks it looks like HTML, it interprets it as HTML! So if the first 256 chararacters have say

<script>run some evil cross-site scripting stuff.....</script>

IE is more than happy to aid-and-abet screwing over the user of IE. What I find really horrid is this:

Well, Microsoft thought different and implemented something they call MIME Type Detection. It means they use the first few hundred bytes of the data and try to guess what the content is. This is a nice idea and even mentioned in RFC 2616:

If and only if the media type is not given by a Content-Type field, the recipient MAY attempt to guess the media type via inspection of its content [...]

Unfortunately Microsoft got the order somehow tangled up: They ignore the sent type and do their guessing first.

Google avoids this problem by putting in the output Http header: Content-Disposition: attachment. This forces all browsers to download the content. Other services recode jpgs, ico’s and the like. But at the end of the day come on guys!

why doesn’t tomcat make it possible to not have jsessionid in urls?

Sunday, February 18th, 2007

I don’t know either! But fortunately I found this great post.

phone usability design notes (part 1)

Friday, February 9th, 2007

I am starting a company, BuildCap. BuildCap’s target market includes groups like the Transportation and Land Use Coalition.

TALC staff, like others, in the non-profit space do field work away from computers, but they still need to interact with the BuildCap software. So this leads to a mandatory phone browser support requirement. As a result, I am doing preliminary research on being able to support phone browsers.

I am using a Samsung A900M phone, which is actually a fairly nice phone, but one that only cost me $40+tax and a 2-year contract with Sprint just before Christmas 2006.

Some notable stats:

  • Java
  • QVGA - The main screen measures 1.78” x 1.53” and sports 262K colors over 240 x 320 pixels
  • 1.3 megapixel camera
  • connects as a USB device to Win XP
  • 47mb memory
  • EVDO data network (fast)

Some of the info about the web browser on this phone:

  • Browser supplier: Teleca
  • Browser Name: Obigo (AU System)
  • Browser version: AU-MIC/2.0 MMP/2.0
  • Markup Languages Supported: WML, XHTML, HTML, Basic/MP
  • Cookies supported: Yes
  • Maximum URL length: 512 characters
  • Transfer protocols supported: HTTP, HTTPS
  • ECMA Script: Yes
  • Multi-part MIME: Yes
  • CSS Background Images: Yes

This phone is a reasonably high-end phone but still arguably affordable. If this phone doesn’t support something then, it is unlikely that any other phone equivalent or lower in price would either. As a result, this is a good first phone to demo with.

So what did I find so far?

Gothas so far:

Using link <a> with the href attribute containing javascript

This doesn’t work at all in the browser. It complains that it needs a handler for this type and dies. This is probably the quickest way to break a site from the perspective of the phone. Tapestry’s LinkSubmit is guilty of this behavior. Since proper css can make a regular submit button look like a link, a proper <input type="submit"> is probably best. For BuildCap, I am going to set up a checkstyle rule that flags uses of LinkSubmit as an error.

Requiring the user to press “enter” key.

This is the second quickest way to break the site. There is no way that a phone browser user can generate the enter key! So if an action needs to be performed, an submit or link must be available.

Redirects

The browser asks for confirmation on every redirect. So multiple redirects are painful, especially redirects that result from security checks. I would suggest designing code to chain code so that all the things that can trigger a redirect vote for a redirect that is only actually executed by a single piece of code.

Dojo seems to have some issues

Still working on this, but dojo seems to not work well on the browser, even though the browser allegedly supports Ecmascript. For example date/timepickers are not working at all. They are not creating their input fields, yet the browser claims there are no “scriptng” (sic) errors. More research is needed.

Color selection limited

Considering how many colors the phone itself can support, this surprised me. The browser looks like it only supports these colors for text:

  • black,
  • blue,
  • green,
  • cyan,
  • red,
  • magenta,
  • brown,
  • light gray,
  • dark gray,
  • light blue,
  • light green,
  • light cyan,
  • light red,
  • light magenta,
  • yellow,
  • and white.

That’s all for now. More to come!

update According to this from Alex of dojo, Obingo’s browser “will be poorly supported”, because(?) “No way to easily get emulator”. Again more research is needed.

hibernate and component querying

Wednesday, October 18th, 2006

Well here is some interestingness with querying for components using the 3.2.0cr5 version of hibernate. (FYI using accessor methods is the way the code was actually written. Direct references to properties in this example used just for clarity.)

Components in hibernate are objects that are represented in the database as a subset of columns with in their container. For example:

In the Java code:

class Foo {
    public Peanuts peanut;
    public int foo1;
    public Bar bar;
}

class Bar {
    public Peanuts peanut;
    public int bar1;
}

class Peanuts{
   public Foo foo;
}

     <class name="Foo">
         <many-to-one name="peanut"/>
         <property name="foo1"/>
         <component name="bar">
             <property name="bar1"/>
         </component>
    </class>

will result in a database table ‘FOO’ that looks like:

PEANUT, FOO1, BAR1

Now the problem I have is that I wanted to retrieve Bars. Using a PostLoadEventListener looking for Foo’s, I wanted to fix up the reference Bar had to Peanuts, like this:


    public class FooPostLoadListener implements PostLoadEventListener {
        private static final long serialVersionUID = 1L;

        public void onPostLoad(PostLoadEvent event) {
            if ( event.getEntity() instanceof Foo) {
                Foo ts = (Foo)event.getEntity();
                ts.bar.peanuts = ts.peanuts;
            }
        }
    }

But of course the entity being loaded is a Bar not a Foo.

Now there is the possible use of the <parent> with in the Bar component. However, that means that a publically visible method is available that should never be used. (<parent> doesn’t have the ability to set the property using ‘field’ access).

The next step was creating a setParent(Foo) and a Foo getParent() on bar:


class Bar {
    public Peanuts peanut;
    public int bar1;
    public void setParent(Foo f) {
       peanuts = f.peanuts;
    }
    public Foo getParent() {
        return peanuts.foo;
    }
}

     <class name="Foo">
         <many-to-one name="peanut"/>
         <property name="foo1"/>
         <component name="bar">
             <parent name="parent"/>
             <property name="bar1"/>
         </component>
    </class>

Now this doesn’t work because the setParent() method is called before Foo has any of its fields instantiated. This actually makes a lot of since otherwise when you are reading in the result set, there is a lot of juggling to get the data ordered in the right way for what the code needs.

Unfortunately, inspite of all this rework at the end of it all, querying for a component returns the component without the parent Foo set. I was hoping that accessing the parent Foo via a call to getParent() would trigger a load of Foo but it doesn’t.

How to do redirects in tapestry

Friday, October 6th, 2006

How to do client-side redirects-after-post (taken from someone else’s sample code):

public abstract class somePage extends ATapestryPage {
   @InjectObject("engine-service:page")
   public abstract IEngineService getPageService();
   public ILink theListenerMethod() {

/*
Redirect to next page. SECURITY NOTE - do not use simple page activation Instead, we return an ILink because that instructs Tapestry to do a redirect-after-post. Redirect-after-post protects against a security vulnerability in which a user may log in without a password simply by using a browser that has been logged out, then using the Back button to go back to the first screen after the login screen and pressing refresh. Without redirect-after-post this would re-post the login info and they’d be logged in!
*/

      ILink redirectTo = getPageService().getLink(false, WelcomePage.PAGE_NAME);
      return redirectTo;
   }
}

To do a server-side redirect, throw a org.apache.tapestry.PageRedirectException that was created with the desired page to redirect to.