Sunday 16 June 2013

Uncaught TypeError: Object has no method 'merge'

So you are using Handlebars.js for your dynamic content in your Javascript app, and it's almost show time so you are precompiling your .handlebars files and swapping your handlebars.js for handlebars.runtime.js, both of which are the latest version from the Handlebars website... basically following the process laid out by Tal Bereznitskey here

but the first time you run the app locally, you see in your console is a big red error that reads
Uncaught TypeError: Object #<Object> has no method 'merge'

the problem here is that your js app's version of handlebars is different to that the precompiler used.
Even though you downloaded and updated it all today...

The quick and dirty fix here is to copy from
/usr/local/lib/node_modules/handlebars/dist/

the files handlebars.runtime.min.js or handlebars.runtime.js and use that instead of the file you downloaded from the Handlebars website.  Who knows what version of Handlebars you are using now (1.0.10?), but at least its the version that actually works with your precompiler.

File under "ugly but works", I guess.

Monday 27 May 2013

Hiding Javascript validation errors in Eclipse Juno

So you are working on a project that includes some third party Javascript libraries, and your editor is Eclipse (I'm on Juno, but no doubt this issue affects Indigo or even farther back...) - anyhow, you import the .js file into your nice clean project and bang! The Problems tab shows errors in the script

For example, I get errors with libraries like jquery.mobile-1.3.1.min.js
Syntax error on token "Invalid Regular Expression Options", no accurate correction available
and handlebars.js (1.0.0.rc4) raises three
Syntax error on token ",", delete this token
Syntax error on token ")", ( expected
Syntax error on token "]", delete this token
and of course the problem is not "real" - it is just Eclipse's implementation of the Javascript validator.

So if you are a braver coder than me you could edit these files and fix the issues and hope that doesn't break any other part of the library :/  OR you can suppress the errors in Eclipse.

However you don't want to suppress all Javascript validation because then you wouldn't see your own errors! (And I make plenty).  So here is how to exclude just the third party libraries...

1. You want to keep all your third party librarries in a different path to your own .js files - I use a js directory, below that I have a lib directory where jquery et al go.  So thats a path like
<PROJECT>/WebContent/js/lib/*
2. Right click on the Project, navigate thus Properties -> Javascript -> Include Path.

3. Click the Source tab, expand your WebContent node so you can see "Excluded".

4. Select Excluded, click the Edit button, then add an Exclusion pattern of
 js/lib/*
then click Finish, OK, then do a new build if one doesn't kick off automatically.

Now you should have no more phantom error reports from the third party libraries.

Thursday 16 May 2013

How to kill all database connections from your SQL Server restore database script.

So when I'm building an app, especially before launch, I like to have scripts that completely drop and rebuilds my local, local test, and production databases from the relevant DDL files, then add data where needed.

Then I write .bat scripts so I can invoke the same set of scripts for each environment.

This works great except sometimes the DROP DATABASE statement fails due to a lingering connection:
Msg 3702, Level 16, State 4, Server SOURCECRAFT-PC\LOCALDB#C12079B7, Line 13
Cannot drop database "databasename" because it is currently in use.
Msg 1801, Level 16, State 3, Server SOURCECRAFT-PC\LOCALDB#C12079B7, Line 2
Database 'databasename' already exists. Choose a different database name.
Sometimes, maddeningly, you have to close your server connection from SQL Server Management Studio and exit Visual Studio 2012 before whatever connection will let go - which is not terribly productive.

The solution is to add this before your DROP DATABASE script. It quietly kills any lingering connection you might have, allowing your script to work as it should every time, and crucially allowing you to leave Visual Studio 2012 and SQL Server Management Studio open while you drop and recreate your database.
USE [master]
GO
-- this is to kill any connections lingering, like Visual Studio
ALTER DATABASE [databasename]
SET OFFLINE WITH ROLLBACK IMMEDIATE
ALTER DATABASE [databasename]
SET ONLINE
GO
-- real script begins here...
DROP DATABASE [databasename]
GO

Hope that helps you out just a little.

Tuesday 14 May 2013

Fixing Twitter OAuth 401 errors due to server time

So if you're like me, your Twitter app (youpickedafinetimetoleaveme.com) had been happily authorizing user access tokens and secrets via OAuth against Twitter since forever, then all of a sudden bang! You start getting stack traces all over your browser with an Exception a bit like this:

"oauth.signpost.exception.OAuthNotAuthorizedException: Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match."
(For the record, I'm using the excellent Signpost OAuth Java library to handle the low level OAuth functionality, but this error would happen regardless how you handle your OAuth authorizations...)

Now I have a guilty little secret to share. A while back, Twitter updated their API, and there was all this fuss about legacy apps breaking, and well, you know what - mine didn't break, so I ignored all of that, did nothing and went about my day. Until now. Seeing this error happen I thought my laziness had come home to roost. Not an uncommon feeling. So I went and updated the aforementioned Signpost, along with JTwitter and Scribe (it's a long story), and updated some code, and tests pass and it works on my machine just fine, but you know what - when I uploaded it to production it didn't fix a thing.

The actual problem is kinda implied in that last part of the Exception message - "...the signatures did not match". It turns out my Debian server clock time was incorrect. Twitter will 401 an OAuth attempt if the signature is not correct - and sender machine DateTime is part of that check. Local clock was fine.

To check if this is your problem, from the server command line type

date

and if that date doesn't look right, this is probably your problem. Even if it isn't, having your server in sync can only be a good thing, right? Press on to see how to update your server clock on Debian.

Turns out more recent distributions of Debian have some issue that prevents clock sync from the server hardware - so they generally drift out of time unless you are running something that keeps it in sync via NTP. So the solution to this problem is simples:  update your server clock.

Here's how I did that, from command line on the server machine:

1. Install ntp to keep the machine in sync, and ntpdate as a manual sync utility 

sudo aptitude update 
sudo aptitude install ntp 
sudo aptitude install ntpdate


2. Check the current server date

date

3. Sync via a remote time server

sudo ntpdate pool.ntp.org


4. Check the current server data again, it should be different now, dare we say it - correct?

date


5. Lastly, set ntp started on your machine

/etc/init.d/ntp start


And you're done.

Tuesday 29 January 2013

How to open 2 instances of Adobe Flash Builder 7 on Mac OSX

One of my clients creates a source code repository branch per feature being worked on, and sometimes the need comes up to have multiple instances of Adobe Flash Builder open, each on a different branch.

Childs play on other OS but in OSX if you double click on the Application icon it just brings your original instance to the front.  Terminal to the rescue!

Open Terminal and type (assuming you installed in the default location)

open -n /Applications/Adobe\ Flash\ Builder\ 4.7/Adobe\ Flash\ Builder\ 4.7.app/


(if you installed in non default, edit the above to suit your path, make sure to include the .app part).

Simples.

With thanks to Doug Simon's blog post on running multiple versions of Eclipse

Saturday 17 March 2012

Fixing the "DeployTask cannot be found" error when using the Tomcat 7 Ant tasks on Mac OSX.

So you've got an Ant build.xml script for your Java web application and it works just fine compiling, testing and building your WAR or EAR file. And you manage to ignore your peers who whine on about that Maven thing.

You deploy your application to Tomcat 7, but you do that manually and that's getting boring now so you want to take that last step and script your deploy as well. You kind of like the one click done feel of it, its almost continuous deployment and that is what all the cool kids are into these days so you want some of that action yourself. You're only human.

So you went and Google'd and came across the Tomcat Ant task documentation and yea verily it looked good.

So now in your build.xml file you have something like this (I left out a bunch of other Tomcat commands, dont worry if you have those)
<taskdef name="deploy" 
    classname="org.apache.catalina.ant.DeployTask"/>

<taskdef name="undeploy" 
    classname="org.apache.catalina.ant.UndeployTask"/>

<target name="deploy" 
    description="Install web application"
    depends="war">
    <deploy url="${url}" 
        username="${username}" 
        password="${password}"
        path="${path}" 
        war="file:${build}${path}.war"/>
</target>

<target name="undeploy" 
    description="Remove web application">
    <undeploy url="${url}" 
        username="${username}"
        password="${password}"
        path="${path}"/>
</target>

But when you run it via Terminal like so

adrian$ ant -Dusername=adrian -Dpassword=pass -f build.xml deploy

you see this really annoying error (even though it worked in your IDE, or maybe it worked on the first machine but not now)

BUILD FAILED
build.xml:11: taskdef class org.apache.catalina.ant.DeployTask cannot be found
using the classloader AntClassLoader[]

Here's how I fixed this (on two machines now). Hopefully it will help you too.

First I have a symlink set up to point at my Tomcat installation, like so

ln -s /path/to/where/i/put/Tomcat /Tomcat


so you might do that too, but if not, just replace /Tomcat below with whatever your path to Tomcat is.

Then in Terminal run these 4 lines, supplying your admin password when prompted
sudo cp -p /Tomcat/lib/tomcat-util.jar /usr/share/ant/lib/
sudo cp -p /Tomcat/bin/tomcat-juli.jar /usr/share/ant/lib/
sudo cp -p /Tomcat/lib/tomcat-coyote.jar /usr/share/ant/lib/
sudo cp -p /Tomcat/lib/catalina-ant.jar /usr/share/ant/lib/

So we're just copying 4 JAR files to where your Mac has it's Ant installed.
Restart Terminal and this time you see
...
deploy:
[deploy] OK - Deployed application at context path /ReptileKingdom

BUILD SUCCESSFUL

Fantastic! Back to writing awesome code for you.


Oh and one last thing - if you instead see another error, much like this

build.xml:69: java.io.IOException: Server returned HTTP response code: 401 for URL: http://localhost:8080/manager/text/undeploy?path=%2YourApp

then you need to edit your /Tomcat/conf/tomcat-users.xml file and make sure you have a user in there who has at least manager-script role, but I generally just give all of them like so manager-script,manager-gui,manager-jmx,manager-status.
And of course, the username and password you specify in your deploy call should match those for the user with the roles.

Tuesday 7 February 2012

Fixing "Incompatible JavaHL library loaded" error on Mac OSX

So you use Eclipse on your Mac and you want to work with a Subversion version control system, so you installed Subclipse and everything seemed fine... and maybe it even used to work OK last time..., but now, today, when you need it most - you get an error that says:
Incompatible javaHL library loaded
and it probably says version 1.7 too.

Whats happening is that the subversion files you are trying to work with are at a more recent version than you have available locally. Here's how to fix it.

  1. Make sure you have latest Subclipse installed, go to the Subclipse site, click on Download and Install, grab the appropriate Eclipse update URL, then in Eclipse, go to Help, Install New Software, and add that URL as a new update site. After it loads, select everything it offers and finish the install. Here is the Eclipse update site for version 1.8
    http://subclipse.tigris.org/update_1.8.x
  2. Now we need to install Subversion client binaries on your machine, Collabnet don't have the latest but luckily UberSVN do, so go to the UberSVN download page, select the OSX tab, then click to download the Subversion Client 1.7.2. Note: it's not that big blue call to action button! It's the links below. Once you have the client, go ahead and install it.

  3. Quickly add Subversion to your path, I do this by editing ~/.profile and adding
export PATH=/opt/subversion/bin:$PATH
Restart Eclipse, and with an ounce of good fortune, Subversion and Subclipse now work again.

One last note: if, just like me, you found that big blue call to action button on UberSVN's download page just too tempting to resist... there is an unofficial (but seems to be written by a UberSVN's developer) Mac OSX UberSVN uninstaller script to tidy that up.
Worked a treat for me.