Fixing EhCache / Tomcat memory leak warnings.
We were receiving messages such as this:
The web application [/services] appears to have started a thread named [net.sf.ehcache.CacheManager@37ce6a10] but has failed to stop it. This is very likely to create a memory leak.
The solution, in our groovy based spring web app that uses annotation based configuration, was to register the net.sf.ehcache.constructs.web.ShutdownListener class with the context in our class that extends WebApplicationInitializer via an overridden onStartup() method, something like this:
import net.sf.ehcache.constructs.web.ShutdownListener import org.springframework.web.WebApplicationInitializer ... public class CustomWebApplicationInitializer implements WebApplicationInitializer { ... @Override public void onStartup(ServletContext servletContext) throws ServletException { ... createContext(...) ... } private AnnotationConfigWebApplicationContext createContext(final Class>... annotatedClasses) { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext() context.register(annotatedClasses) context.register(ShutdownListener) return context } }
More information can be found here: http://ehcache.org/documentation/operations/shutdown
Adding a custom test phase to Grails 2.3
Here's a snippit showing how to add a custom test phase and to exclude other phases, this code is pretty raw but should help you in figuring things out. The way that test phases are created has changed alot since grails 1.3 and the grails documentation doesn't show how to do it. Also as of November 2013 Luke Daley's blog post on the subject from the grails 1.3.7 days has disappeared.
scripts/_Events.groovy
buildRawGrailsEnv = { return System.getProperties().get('grails.env').toString().toLowerCase() } eventTestPhasesStart = { phasesToRun -> // background: in our codebase we have an environment called 'remote' and the only valid phases for that environment is the new 'remote' phase. // if the environment is not 'remote' then do not add the new phase. String rawGrailsEnv = buildRawGrailsEnv() if (!rawGrailsEnv.equals('remote')) { return } // exclude all other phases except the new 'remote' phase. def phasesToExclude = phasesToRun.collect { return it } phasesToRun << "remote" phasesToExclude.each { phasesToRun.remove(it) } def remotePhaseConfigurer = new IntegrationTestPhaseConfigurer(projectTestRunner.projectTestCompiler, projectLoader) projectTestRunner.testFeatureDiscovery.configurers.remote = remotePhaseConfigurer def remoteTestTypeName = "remote" def remoteTestDirectory = "remote" def remoteTestMode = new GrailsTestMode(autowire: true, wrapInTransaction: true, wrapInRequestEnvironment: true) def remoteTestType = new GrailsSpecTestType(remoteTestTypeName, remoteTestDirectory, remoteTestMode) projectTestRunner.testFeatureDiscovery.testExecutionContext.remoteTests = [remoteTestType] } remoteTestPhasePreparation = { // called at the start of the phase println "*** Starting remote tests" integrationTestPhasePreparation() } remoteTestPhaseCleanUp = { // called at the end of the phase println "*** Finished remote tests" integrationTestPhaseCleanUp() }
ASUS P5K-E Wifi with ATI 5870 Triple Screen hackintosh
Guide Version: 1 – 17/April/2011
Hardware
- Mobo: ASUS P5K-E Wifi/AP (Network: Marvel 88E8056 Gigabit, Vendor: 0×11ab, Device: 0×4364, SS Vendor: 0×1043, SS: 0×81f8)
- CPU: Intel E8200
- OCZ 2×2GB RAM OCZ2P8002G (Slots A1/B1)
- GFX: HIS 5870 (VendorID: ATI 0×1002, Device ID: 0×6898, Revision ID: 0×0000)
- Optical Drive: Pioneer DVR-218L / 1.02 / SATA
- HDD: Old Seagate 7200.11 SATA drive (for testing, will move to Seagate Momentus XT later)
HIS ATI 5870 Bios: HIS.HD5870.1024.091112.bin from Tech Power-Up, Flashed using ATIWinFlash in Windows (I did this before I used the card in my hackintosh box, unsure if older BIOS revisions work on hackintosh)
ASUS P5K-E Wifi Bios Version: 1305
Needed stuff
- Multibeast 3.4 (latest as of 17/4/2011)
- IBoot (latest as of 17/4/2011)
- Kaybl bootloader – http://www.insanelymac.com/forum/index.php?showtopic=231768 (patch commit revision 700 (09.01.2011))
- DSDTAutoPatcher
BIOS Settings
Load Setup Defaults
- Configure SATA as: AHCI
- ACPI v2: enabled
- JMicron disabled (to be enabled later)
- Suspend Mode: S3 Only
- ACPI 2.0 support: Enabled
The procedure and notes
Boot IBoot cd
Problem #1:
IBoot comes up with ‘ebios read error’
Solution:
Removing SATA cable, then booting IBoot CD, then inserting SL DVD, then pressing F5 then quickly connecting HDD SATA Cable back to HDD allows system to boot.
Problem #2:
Install CD fails to boot to a GUI. The Apple logo appears, following by spinning circle but no GUI appears
Solution 1:
Use Rebel EFI to boot the DVD instead of IBoot (also means you don’t have to fiddle with SATA cables, however this, didn’t allow me to get native res and accelerated graphics when using it to boot from the HDD)
Solution 2:
Use iBoot-ATI-5xxx-3.iso to boot the DVD (although unavailable from tonymac site and you still have to fiddle with SATA cables)
Create 2 partitions using disk utility before continuing with the installer (one for boot, one for bootable backup) GPT style, not MBR.
Install OSX. Might say failed after copying the files, ignore and reboot using IBoot ATI boot cd.
Install OSX 10.6.7 combo update, wait till the restart prompt appears, don’t click it, then run MultiBeast, select EasyBeast and PCIRootUID fix
Could boot off HDD using IBoot ATI boot cd with boot arguments (just type in once you cursor over to the HDD in the IBoot chameleon boot menu):
PCIRootUID=1
Installed experimental ATI Chameleon bootloader (without ATI support attempting to boot from HDD resulted in the graphics cards fans being turned on full – power cycle required!)
This allowed booting from HD but not to GUI
Could get into single user mode from HDD with:
arch=i386 PCIRootUID=1 -s
Create a DSDT file using DSDTAutoPatcher (selecting Asus, P5K-E Wifi/AP), install as /Extra/dsdt.aml
Remove the following kexts from /Extras:
EvOreboot.kext
LegacyAppleRTC.kext
NullCPUPowerManagement.kext
Could then boot with arch=x86_64 (no other options)
Display port would not work
Installed Kaybl bootloader – http://www.insanelymac.com/forum/index.php?showtopic=231768
sudo su – gzip -d boot.gz
mv boot kaybl-boot
mv /boot/boot.multibeast
cp kaybl-boot /boot
FYI, the unarchived kaybl-boot file was 297152 bytes long, the one i had before that was 199712 bytes long
Made no difference, but there was some settings to try:
Set AtiConfig=Uakari in boot plist after looking at source here: http://forge.voodooprojects.org/p/chameleon/source/tree/HEAD/branches/Kabyl/i386/libsaio/ati.c
That enabled DisplayPort and a second monitor using the top DVI port, plugging in an HDMI cable resulted in all three monitors being detected but only the output on the displayport worked.
Moving the DVI cable to the bottom DVI port restored a display on a second monitor, still only 2 displays however.
Using AtiConfig=Zonalis only enabled bottom DVI port (this was probably the previous default)
Weirdly, after a reboot (using AtiConfig=Uakari, still in boot plist from before), with DVI cable in bottom port, DVI-VGA in top port and Display Port all three monitors worked! Need to cold boot to check it works twice.
Yay, still works after a cold boot, GFX done!
Wifi and JMicron IDE not working yet.
Went back into bios:
JMicron Controller: enabled
Controller Mode: AHCI
Rebooted, JMicron JMB363 AHCI listed in System Profiler ‘Serial-ATA’ section, had a Pioneer DVR-110D connected via IDE cable, popped in a DVD and it appeared on the Desktop.
Note: From Multibeast selected Lnx2Mac Realtek RTL81xx driver, which fired up another installed, installed ‘Release’ version of driver, rebooted – that failed, killed regular ethernet because it moved the IONetworkingFamily.kext driver to my desktop, removed /S/L/E/RealtekRTL81xx.kext, restored IONetworkingFamily.kext to /E/E)
Realtek 8187L driver on their site is for OSX 10.5 which some people report as working in 32bit mode, but we’re using x86_64 so just gonna leave it as not-working.
Aside form the Wifi, all the hardware seems to be working!
34 Pin IDC to 25 Pin Female D-Sub floppy drive pin mapping for Magic Super Griffin
(and probably MGD2, etc)
I cracked open my Magic Super Griffin today after finding an old external floppy drive (FDD) that I wanted to hook up to it. I was expecting to have to look at chip pinouts and signals to figure out which pins were which on the 25-pin connector but to my surprise there was space on the motherboard for a 34pin IDC connector. So the signals can and pinout could be taken directly from that. The FDD controller chip on the SMG, for reference, is a socketed (!) Motorola MCS3201FN - http://www.datasheetarchive.com/pdf-datasheets/Datasheets-111/DSAP0039438.html. The datasheet reveals that the controller can handle up to 1.4M drives too.
\ 13 12 11 10 09 08 07 06 05 04 03 02 01 / \ 25 24 23 22 21 20 19 18 17 16 15 14 /
The pins above are taken looking directory at the female pin (cable) side of the D-Sub connector.
The pins of the IDC connector are numbered from left to right, vertically, from the component side of the board.
01 02 03 04 … 33 34
The pin mapping is thus:
D-Sub - IDC - Signal 01 - 01,03,...,33 - GND 02 - 08 - /INDEX 03 - 26 - /TRK00 04 - 28 - /WPT 05 - 30 - /RDATA 06 - 34 - /DSKCHG 07 - NC - NC 08 - NC - +5V 09 - NC - NC 10 - NC - NC 11 - 16 - /MOTEB 12 - 22 - /WDATA 13 - 24 - /WGATE 14 - 02 - /REDWC 15 - 32 - /SIDE1 16 - 18 - /DIR 17 - 20 - /STEP 18 - 01,03,...,33 - GND 19 - 01,03,...,33 - GND 20 - 01,03,...,33 - GND 21 - 01,03,...,33 - GND 22 - 01,03,...,33 - GND 23 - 01,03,...,33 - GND 24 - 01,03,...,33 - GND 25 - 01,03,...,33 - GND Shield - 01,03,...,33 - GND
With the above information I'm now able to make a suitable cable to connect up any standard PC floppy disk drive. I don't know which model drives are actually compatible. Though I would suggest checking out the Datasheet for the FDD controller chip. If you have any success please let me know so I can share the information with others.
BTW, If you didn't know already a Super Magic Griffin is a PC Engine console backup unit. With it you can load dumped ROM images into the SMG and then run them on your PC Engine console. The unit is basically a ROM emulator with FDD and Parallel I/O connections. They were manufactured by Front Fareast Co. Ltd. (Taiwan).
No-Fuss Tomcat 5.5 installation on OSX 10.5 (December 2009)
After a bit of googling on the topic I couldn't find a decent guide of how to install Tomcat 5.5 on OSX. Here's how I did it.
Download the apache-tomcat-5.5.28.zip zip file from 'Core' section of the Tomcat 5.5 download page from here: http://tomcat.apache.org/download-55.cgi
Download the apache-tomcat-5.5.28-admin.zip zip file from the same page
Open a terminal window.
# perform following operations as root
sudo su -
# unpack tomcat
cd /Library
unzip ~/downloads/apache-tomcat-5.5.28.zip
unzip ~/downloads/apache-tomcat-5.5.28-admin.zip
mv apache-tomcat-5.5.28 Tomcat5
# remove the holding page for the message about the admin webapp not being included by default
rm -rf /Library/Tomcat5/webapps/ROOT/admin
# create tomcat group and user
dscl . -create /groups/tomcat
dscl . -create /groups/tomcat Password "*"
dscl . -create /groups/tomcat PrimaryGroupID 498
dscl . -create /groups/tomcat RealName "Apache Tomcat Users"
dscl . -create /users/tomcat
dscl . -create /users/tomcat Password "*"
dscl . -create /users/tomcat UniqueID 498
dscl . -create /users/tomcat PrimaryGroupID 498
dscl . -create /users/tomcat RealName "Apache Tomcat Server"
dscl . -create /users/tomcat NFSHomeDirectory /var/empty
dscl . -create /users/tomcat UserShell /usr/bin/false
# Hide the tomcat user (and all other users with a UniqueID less than 500) from the Mac OS X GUI
defaults write /Library/Preferences/com.apple.loginwindow Hide500Users -bool true
# fix permissions
cd /Library
chown -R tomcat:tomcat Tomcat5
chmod +x Tomcat5/bin/*.sh
# use a text editor to create a launch script
mate /Library/LaunchDaemons/org.apache.tomcat5.plist
paste in the following xml content and save the file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EnvironmentVariables</key>
<dict>
<key>CATALINA_HOME</key>
<string>/Library/Tomcat5</string>
<key>CATALINA_OPTS</key>
<string>
-server
-Xmx256m
-Dfile.encoding=UTF-8
-Djava.awt.headless=true
-Duser.language=en
-Duser.timezone=GMT+0
</string>
<key>JAVA_HOME</key>
<string>/Library/Java/Home</string>
</dict>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<true/>
</dict>
<key>Label</key>
<string>org.apache.tomcat5</string>
<key>ProgramArguments</key>
<array>
<string>/Library/Tomcat5/bin/catalina.sh</string>
<string>run</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>UserName</key>
<string>tomcat</string>
</dict>
</plist>
Configure the tomcat users
mate /Library/Tomcat5/conf/tomcat-users.xml
paste in the following xml content and save the file
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="tomcat"/>
<role rolename="role1"/>
<role rolename="manager"/>
<role rolename="admin"/>
<user username="tomcat" password="tomcat" roles="tomcat"/>
<user username="both" password="tomcat" roles="tomcat,role1"/>
<user username="role1" password="tomcat" roles="role1"/>
<user username="admin" password="secret" roles="admin,manager"/>
</tomcat-users>
Finally, start tomcat
launchctl load -w /Library/LaunchDaemons/org.apache.tomcat.plist
You can now start your browser and point it to:
http://localhost:8080
You can login to both the manager application and the admin application using the username: 'admin' and the password: 'secret'
Creating GMock expectations for methods that have a closure as a parameter
If like me you want to test as much of your grails/groovy application as possible then at some point you'll need to create a unit test for a method that accepts a closure as an argument. GMock has the ability to use a 'match' closure to check to see if the arguments passed o your mock object are what you expect. The example from their site is:
mockLoader.put("test", match { it > 5 }).returns("correct")
play {
assertEquals "correct", mockLoader.put("test", 10)
}
The play closure calls the mockLoader instance's put method and the second parameter is passed to the match closure and if that closure returns true the value returned by the mockLoader instance will be the string 'correct'.
I had a method like this which I wanted to call and needed to mock out the deviceCriteria object and have the return value of the call to 'get' always return a fixed value so that other code in the test would behave correctly for the rest of the test.
protected Long countDevicesForLicense() {
grails.orm.HibernateCriteriaBuilder deviceCriteria = Device.createCriteria()
deviceCriteria.get{
eq("license", this)
projections {
countDistinct "id"
}
}
}
The gmock test for this looks like this:
/**
* Tests that a device cannot be added to a license that cannot have more devices added to it
*/
void testAddDevicesToFullLicense() {
def deviceCountResult = 10
def mockDevice = mock(Device)
mockDevice.static.createCriteria().returns( mock(grails.orm.HibernateCriteriaBuilder) {
get(match { arg ->
arg instanceof Closure
}).returns(deviceCountResult)
})
play {
License license1 = new License(name: 'Full', maxDevices: 10)
Device device1 = new Device(name: 'Test device')
assertFalse license1.canAddDevice(device1)
}
}
Here, the canAddDevice() method internally calls the countDevicesForLicense() but as this is a unit test, not an integration tests no database is available so using a real HibernateCriteriaBuilder object would fail. Thus we either have to mock out the database objects or create a partial mock. And before anyone says anything - yes, a partial mock here would be better, but that's for another day.
So, the code above sets up an expection on the createCriteria static method of the Device domain class which says the method must be called and when it is called it returns a mock grails.orm.HibernateCriteriaBuilder object that has a 'get' method which should always return the value assigned to 'deviceCountResult'.
If you just tried:
...
get().returns(deviceCountResult)
...
then you'd find the expectation for the 'get' method would fail.
The important point is the match closure that checks to see if the argument passed is a Closure.
Hope this helps!
ATI and Dell 2709W displayport/eyefinity problems and solutions
No display during boot?, No eyefinity in XP?, Can't run three screens in XP? Me too.
So, a while back I got a Power Color 4850 card with a displayport port and connected it up to my Dell 2709W monitor and it didn't work right. 'Stupid new technology' I thought.
The symptoms of it's failure to work were:
1) no display during bootup
2) 640x480 max resolution that the monitor would display once in Windows
3) selecting higher resolutions resulted in a 640x480 display that you could pan around.
4) sometimes the ATI drivers would report a "The system has detected a link failure and cannot set the requested resolution and refresh rate on your DisplayPortTM display. Your display might not support the requested resolution or there may be an issue with the cable connecting the display to your computer"
Displayport port
yes, displayport port
Whoever thought of calling a new technology used to connect displays to devices 'displayport' needs to be given a dunce hat, be chained up somewhere in public so we that can all go and laugh at him and call him an idiot.
Why?
Well, I've got a 'dvi' port, an 'hdmi' port, a 'vga' port and, wait for it, a 'displayport' port.
*sigh*
Tech support call scenario:
Tech guy: Is your monitor connected via displayport?
Customer: yes
Tech guy: And it doesn't work?
Customer: nope, i get no display, I've got my cable plugged in, but nothing
Tech guy: On the monitor, what input is selected?
Customer: Umm, let me check: 'Displayport'
Tech guy: What does your cable look like?
Customer: It's got two large white connectors on either end.
Tech guy: that's a DVI cable, not a displayport cable
Customer: Well, it connects to a display port on the back of the computer, so it's a display port cable right?
Tech guy: No the idiots that came up with the displayport technology gave it a stupid name.
Tech guy: Just select DVI on your monitor instead of 'Displayport'
Customer: Oh yeah, that fixed it.
Tech guy: Great, you've no idea how many calls like that I get
Other tech guy: Another consumer confused by 'displayport'?
Tech guy: yup
Both tech guys: *sigh*
Grails 1.1.1 URL mapping and reverse mapping example
As there's not many examples of Grails 1.1.1 URL Mappings and examples of using them from within GSP files I thought I'd share this one with everyone.
Hosting/Deploying Ruby On Rails apps on Windows
Using Mongrel and Apache with virtual hosts
So recently I've been getting on board the Ruby On Rails bandwagon. Well, not so much the Rails wagon but definately the Ruby wagon, anyway, I digress. If like me you've heard great things about Ruby on Rails and then tried it and ended up with some neat little web-app that you want to deploy but only have access to a Windows Server for deployment that for some reason is running apache and not IIS then here's how to get a vhost up and pointing to your Ruby app.