July 2009 Archives

Nothing is more fun at 10:30pm than a very cryptic error message that comes up while you’re trying to restore from a backup. Well, ok, one thing is. A cryptic error message that has 0 Google results.

Artifactory threw one of these at me tonight so I thoguht I’d get something into Google for the next poor sod that stumbles upon this issue.

If you export an Artifactory system configuration (at least as of v2.0.2) without selecting the ‘create a zip archive (slow!)’ option, you’ll see this when you attempt to import it: artifactory_import_fail.jpg

The solution: as fast as you want to get home to play WoW, go the slow route and create a zip archive. It imports without issue.

0 Votes

Somehow I had survived in the Java wold until now without ever having the pleasure of writing an MBean. MBeans and JMX in general are really cool, but like those full coverage integration tests, they’re one of those things that often slips through the cracks until you have your first major production incident.

This time I’m trying to be good. I’m actually implementing the configuration harness that I’m using for all of my applications with a built in Standard MBean. This MBean provides easy JMX access to inspect and update configuration during runtime.

I followed this tutorial to get going. Note that it has no date (always date your technical blog entries!) It’s pretty good but I had to jump through a couple of hoops to get it working. Here is the story of those jumps.

A Singleton Can Not Be a Standard MBean

I didn’t see this mentioned anywhere, but it turns out to be true. Standard MBeans must have a public default constructor. If they do not, you’ll see this friendly stack trace:

java.lang.NullPointerException
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:303)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:482)
    at foo.bar.Configamajig.bootstrap(Configamajig.java:74)

Yeah, it took me awhile to figure that out.

Anyway, I solved the problem by creating a static class adapter for my singleton. The static adapter just proxied the methods of the singleton with a provided public default constructor. For this to be reliable I make sure that I bootstrap my singleton before I create the MBean (just in case it calls some of those methods).

MBean Concrete Class Naming Is Not Flexible

The example had an MBean interface HelloMBean with a concrete implementing class by the name Hello. As it turns out this was not just to make the tutorial easy to follow. It’s required for the MBean to work! This turned out really nice since my concrete class was an adapter (per the above step). As a result my MBean interface must contain the work ‘adapter’ to comply with this convention.

The guys who came up with this must have forgotten that convention over configuration implies that you can override the convention with configuration if you so desire.

Anyway, to help you Google searcher’s find this solution, here’s the stack trace:

javax.management.NotCompliantMBeanException: MBean class foo.bar.ConfigamajigMBeanImpl does not implement DynamicMBean, neither follows the Standard MBean conventions (javax.management.NotCompliantMBeanException: Class foo.bar.ConfigamajigMBeanImpl is not a JMX compliant Standard MBean) nor the MXBean conventions (javax.management.NotCompliantMBeanException: foo.bar.ConfigamajigMBeanImpl: Class foo.bar.ConfigamajigMBeanImpl is not a JMX compliant MXBean)
    at com.sun.jmx.mbeanserver.Introspector.checkCompliance(Introspector.java:160)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:305)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:482)
    at foo.bar.Configamajig.bootstrap(Configer.java:75)
0 Votes

The team at Apple likes to keep us on our toes. They seem to change this command a lot. In leopard, you can flush your local DNS resolver cache with this command:

dscacheutil -flushcache

If you’re still on Tiger, you will need to use the old command:

lookupd -flushcache
0 Votes

Since Grails v1.1.1 has come out, there has been a strange issue. It seems to sneak up on me every time something important happens, like a production release. Grails throws an exception and I see an error page on my web browser. The exception always looks something like this:

2009-07-16 21:10:16,923 ERROR   org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver:60        groovy.lang.MissingPropertyException: No such property: save for class: foo.Bar
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingPropertyException: No such property: save for class: foo.Bar
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:92)
       ...
Caused by: groovy.lang.MissingPropertyException: No such property: save for class: foo.Bar
        at foo.BarController$_closure8.doCall(BarController.groovy:105)
        at foo.BarController$_closure8.doCall(BarController.groovy)

Research has revealed that other people face this issue as well. Some solutions that people have proposed:

  • Wait a few minutes and try again
  • Restart your application server (this seems to work well for me)
  • run MyDomainClass.count in your Bootstrap.groovy
  • run MyDomainClass.get(-1) before you attempt save

These all seem like black magic to me, though. I wanted to actually understand what was going on. I found the related JIRA (GRAILS-4580) and even the commit that Graeme made to fix it (which will be available in grails 1.2).

After everything I’ve read it seems like it’s another problem with Hibernate proxy objects not getting initialized correctly. This, however, does not explain why it’s been fixed with an application server restart for me each time, or if there’s anything I can do to avoid it while I’m still using Grails v1.1.1.

My plan going forward: Do not change my approach. When I see this issue in the future I’ll continue to attempt black magic. If I have a show stopper issue, I’ll apply the fix to grails v1.1.1.

0 Votes

Configuration can be a bit hairy to test in grails unit tests. While there is an official technique that I found in a JIRA that looks like this:

mockConfig '''
john.doe.name = "bill"
'''

I’ve never gotten it to work. I’ve fallen back to using the Groovy provided meta-programming techniques. This means you need to mock the configuration differently depending on how you access your configuration.

No matter what, start by creating a ConfigObject()

def mockedConfig = new ConfigObject()
mockedConfig.john.doe.name = "bill"

The next step depends on how you’re accessing config in the code you’re testing. If you’re using ConfiguratoinHolder, try this

ConfigurationHolder.config = mockedConfig

On the other hand, if you’re using grailsApplication, this will work better.

GrailsApplication.metaClass.getConfig = {-> mockedConfig }

This is yet another reason to be consistent in your coding. If you’re not consistent you may end up mocking both.

0 Votes

Maven is a life saver for Java. It provides some much needed convention, but at the same time it can be really tricky to figure out how to do some basic configuration. One problem I struggled with was setting up an Artifactory repository which required authentication for the uploading and downloading or jars.

To save you some time, here are some steps with the minimal required configuration:

  1. Install artifactory as described on their website
  2. Create a user that you will use for access. Make sure that they have access but they do not need to be an administrator.
  3. Encrypt this user’s password mvn --encrypt-password . You should get a result that looks something like this: {COQLCE6DU6GtcS5P=}
  4. Create your ~/.m2/settings.xml file and add this content to it. This will teach your maven how to download libraries from your repository.
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<pluginGroups> 
<pluginGroup>org.grails</pluginGroup></pluginGroups> 
  <servers>
    <server>
        <id>myrepo.example.com</id>
        <username>johndoe</username>
        <password>{the encrypted password from the previous step}</password>
    </server>
  </servers>
  <profiles>
    <profile>
      <id>default</id>
      <repositories>
          <repository>
              <id>myrepo.example.com</id>
              <url>http://myrepo.example.com:8090/artifactory/repo</url>
          </repository>
      </repositories>
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>default</activeProfile>
  </activeProfiles>
</settings>
  1. Add this to each of your pom.xml files (or to your project root pom). This is how your projects know to deploy your libraries. The user name and password will be used from settings.xml which is why it’s important for the two server IDs to match.
    <distributionManagement>
        <repository>
            <id>myrepo.example.com</id>
            <name>myrepo.example.com</name>
            <url>http://myrepo.example.com:8090/artifactory/libs-releases-local</url>
        </repository>
        <snapshotRepository>
            <id>myrepo.example.com</id>
            <name>myrepo.example.com</name>
            <url>http://myrepo.example.com:8090/artifactory/libs-snapshots-local</url>
            <uniqueVersion>false</uniqueVersion>
        </snapshotRepository>
    </distributionManagement>
0 Votes

Maybe you’re experiencing trouble with your IDE debugger, or you’re just a hard core VI kind of guy. Either way sometimes you need something a little more than println. Lucky for you Groovy has a pretty powerful yet undocumented debugging tool built right in called the Object Browser. It’s far from a full blown debugger, but it’s a great object inspector.

To use this inspector just add this anywhere in your Groovy program where someObject is the object that you’d like to inspect:

groovy.inspect.swingui.ObjectBrowser.inspect(someObject)

You’ve probably already noticed the swingui part of it. This brings up a handy dandy window for interactive inspection. It looks something like this:

groovy_inspect.jpg

But wait, there’s more. If you’re working with closures, as is the case almost everywhere in Groovy on Grails, try inspecting the object owner. This will inspect the container for the closure you’re currently running, which provides a ton vital information.

0 Votes

Sometimes when you install stuff on your mac or just turn on a service it’s very hard to figure out important locations like the installation directory. One very annoying case is the local apache directory used by OS X 10.5’s built in Web Sharing. It took me a sudo find ./ -name PoweredByMacOSX.gif to figure this out!

Anyway, hopefully I can save you a couple minutes. The default document directory for web sharing on OS X Leopard is:

/Library/WebServer/Documents/

0 Votes