<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BarneyBlog &#187; java</title>
	<atom:link href="http://www.barneyb.com/barneyblog/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.barneyb.com/barneyblog</link>
	<description>Thoughts, rants, and even some code from the mind of Barney Boisvert.</description>
	<lastBuildDate>Mon, 02 Mar 2020 13:20:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A Word About Development Environments</title>
		<link>https://www.barneyb.com/barneyblog/2010/09/27/java-development-environments/</link>
		<comments>https://www.barneyb.com/barneyblog/2010/09/27/java-development-environments/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 03:03:32 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1594</guid>
		<description><![CDATA[I saw this today, and thought it hilarious:
Java, being a mainstream programming language, has attracted major software companies to pour money and human effort into it. As a consequence, a lot of good integrated development environments (IDEs) are out there. Of course, there is nothing wrong with being a real programmer by using the good [...]]]></description>
			<content:encoded><![CDATA[<p>I saw this today, and thought it hilarious:</p>
<blockquote><p>Java, being a mainstream programming language, has attracted major software companies to pour money and human effort into it. As a consequence, a lot of good integrated development environments (IDEs) are out there. Of course, there is nothing wrong with being a real programmer by using the good old BSD vi plus a shell. Or (a little more civilized), emacs. Others who would like a more modern IDE will certainly enjoy eclipse. The main strength of eclipse, besides being totally free, is that it's built in with unit testing (JUnit) and refactoring, the two ingredients of so-called agile programming or extreme programming. It also integrates version control seamlessly. It's much more usable than the MS Visual Studio and VSS dual in nearly every aspect, except of course for generating standard-incompliant Java code.</p></blockquote>
<p>&#8211; Christopher M. Brown, from <a href="http://www.cs.rochester.edu/~brown/242/assts/bh_learning/learning.html">http://www.cs.rochester.edu/~brown/242/assts/bh_learning/learning.html</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2010/09/27/java-development-environments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I&#039;m on CFPanel This Evening</title>
		<link>https://www.barneyb.com/barneyblog/2009/09/08/im-on-cfpanel-this-evening/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/09/08/im-on-cfpanel-this-evening/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 16:58:05 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=1079</guid>
		<description><![CDATA[This evening (depending on where you live) is CFPanel, and Mark Mandel, Brian Kotek, and myself are talking about CF and Java integration.Â  It starts at 5pm PST (8pm EST) if you're interested in attending live, or will be available as a recording after the fact.
]]></description>
			<content:encoded><![CDATA[<p>This evening (depending on where you live) is <a href="http://cfpanel.com/index.cfm/2009/9/3/Episode-5--ColdFusion-and-Java-Integration">CFPanel</a>, and Mark Mandel, Brian Kotek, and myself are talking about CF and Java integration.Â  It starts at 5pm PST (8pm EST) if you're interested in attending live, or will be available as a recording after the fact.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/09/08/im-on-cfpanel-this-evening/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Project Euler Test Harness</title>
		<link>https://www.barneyb.com/barneyblog/2009/03/05/project-euler-test-harness/</link>
		<comments>https://www.barneyb.com/barneyblog/2009/03/05/project-euler-test-harness/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 04:39:57 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[project euler]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=710</guid>
		<description><![CDATA[Project Euler is a collection of mathematics/computer science problems, as you probably already know.  I've solved almost 50 of them so far, and I've developd a collection of utilities to make my job easier.  Some of them (factorization routines, prime generators, etc.) I'm not going to share as they are fundamental to solving certain problems.  [...]]]></description>
			<content:encoded><![CDATA[<p><a ="http://projecteuler.net/">Project Euler</a> is a collection of mathematics/computer science problems, as you probably already know.  I've solved almost 50 of them so far, and I've developd a collection of utilities to make my job easier.  Some of them (factorization routines, prime generators, etc.) I'm not going to share as they are fundamental to solving certain problems.  However, I will share my test harness, as it's probably generally useful, and it contains no "secrets".</p>
<p>Why build a custom harness?  Well, I originally considered using JUnit (or whatever) as a simple runner, but since there isn't anything to test, it didn't feel right.  It also doesn't provide a good way to get timing information for the runs.  And since I was originally using strictly Groovy, I didn't want to impose any more "ceremony" than I needed to.  I've since started doing some problems in Java simply for the performance (as well as converting some of those "secret" routines), and have generalized my harness.</p>
<p>First, here are the file templates for Groovy:</p>
<pre>import util.Runner

new <span style="color: #ff0000;">Runner</span>() {
  <span style="color: #0000ff;">// put some code here, eh?</span>
}</pre>
<p>and for Java:</p>
<pre>import util.Runner;
import util.java.Solver;

public class BruteForce {
  public static void main(String[] args) {
    new <span style="color: #ff0000;">Runner</span>(new <span style="color: #339966;">Solver</span>() {
      public Object solve() {
        <span style="color: #0000ff;">// put some code here, eh?</span>
        return null;
      }
    });
  }
}</pre>
<p>As expected the Java version requires quite a bit more ceremony, even though the semantics of the two templates are identical.  The Solver interface (used for Java) is as follows:</p>
<pre>package util.java;

public interface <span style="color: #339966;">Solver </span>{
   public Object solve();
}</pre>
<p>Finally, the <span style="color: #ff0000;">Runner</span> class, which is implemented in Groovy.  As you can see from the templates, it accepts either a <span style="color: #339966;">Solver</span> instance or a Groovy closure, and treats the two in exactly the same way, excepting that it picks between <span style="color: #339966;">Solver</span>.solve() and Closure.call() based on the type.</p>
<pre>package util

import util.java.Solver

class <span style="color: #ff0000;">Runner</span> {

  private static ThreadLocal timer = new InheritableThreadLocal()
  private static int timerCount = 0

  def Runner(solver) {
    this(true, solver)
  }

  def Runner(doIt, solver) {
    if (! doIt) {
      return
    }
    startTimer()
    // this will send an update every five or so seconds
    volatile def updateThread
    updateThread = Thread.startDaemon {
      while (true) {
        Thread.sleep(5000)
        if (updateThread == null) {
          break // after the sleep, before the log
        }
        log("still executing...")
      }
    }
    try {
      log("starting...")
      def result;
      if (solver instanceof <span style="color: #339966;">Solver</span>) {    // the closure/Solver switch
        result = solver.solve()          //  |
      } else { // better be a Closure    //  |
        result = solver.call()           //  |
      }                                  //  V
      stopTimer()
      if (result instanceof String) {
        try {
          result = new BigInteger(result)
        } catch (e) {
          // oh well
        }
      }
      if (result instanceof Integer || result instanceof Long || result instanceof BigInteger) {
        log("result: $result")
      } else {
        def s = "" + result
        if (s.length() > 100) {
          s = s[0..<97] + "..."
        }
        log("result was not numeric: $s", System.err)
      }
    } finally {
      updateThread = null
    }
  }

  def elapsed() {
    get().elapsed
  }

  def formatElapsed(e) {
    def seconds = e.intdiv(1000)
    def millis = e % 1000
    def s = ""
    if (seconds >= 60) {
      s += seconds.intdiv(60) + ":"
      seconds = seconds % 60
    }
    if (s.length() > 0 &#038;&#038; seconds < 10) {
      s += "0$seconds"
    } else {
      s += seconds
    }
    if (millis < 10) {
      s += ".00$millis"
    } else if (millis < 100) {
      s += ".0$millis"
    } else {
      s += ".$millis"
    }
    s
  }

  def log(Object msg, out=System.out) {
    def t = get()
    out.println "[${t.index}: ${formatElapsed(t.elapsed)}] $msg"
  }

  private startTimer() {
    Runner.timer.set(new TimerData(++timerCount))
  }

  private stopTimer() {
    get().stop()
  }

  private get() {
    def t = Runner.timer.get()
    if (! t) {
      throw new IllegalStateException("No timer has been started...")
    }
    t
  }
}

class TimerData {
  def index
  def startDate
  def stopDate

  def TimerData(threadIndex) {
    index = threadIndex
    startDate = new Date()
  }

  def stop() {
    stopDate = new Date()
  }

  def getElapsed() {
    if (running) {
      return new Date().time - startDate.time
    } else {
      return stopDate.time - startDate.time
    }
  }

  boolean isRunning() {
    stopDate == null
  }
}</pre>
<p>There's a lot of stuff going on there, but primarily it's setting up a timing framework, a background thread to tell you it's still running every 5 seconds, and doing some magic with the returned solution.  As you can see, the constructor takes an optional first parameter for whether to execute.  Useful if you have multiple Runners in a single script/class, but only want to run some of them. <a href="https://maxinternet.biz/best-gas-grills-under-300">https://maxinternet.biz/best-gas-grills-under-300</a></p>
<p>It wasn't my intent, but building this out was quite educational in the way the Java/Groovy interplay works.  Write Groovy for whatever you can, and write Java for the bits that need it.  As you can see from the templates, Java requires a lot more work, but it has benefits.  I was quite pleased to be able to use my Groovy harness (which leverages all kinds of Groovy goodness) for my Java solutions.  I originally figured I'd have to port it to Java to use it with both languages, but not the case.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2009/03/05/project-euler-test-harness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eclipse and JUnit</title>
		<link>https://www.barneyb.com/barneyblog/2008/11/06/eclipse-and-junit/</link>
		<comments>https://www.barneyb.com/barneyblog/2008/11/06/eclipse-and-junit/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 05:57:25 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[eclipse]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=548</guid>
		<description><![CDATA[I started building a little Java app this evenings.Â  First time I've done Java SE work in a long time, and it's kind of nice.Â  Not sure why I picked Java instead of Groovy, but whatever.Â  Probably the same reason people go home for the holidays.
In any case, being the good developer I am, after [...]]]></description>
			<content:encoded><![CDATA[<p>I started building a little Java app this evenings.Â  First time I've done Java SE work in a long time, and it's kind of nice.Â  Not sure why I picked Java instead of Groovy, but whatever.Â  Probably the same reason people go home for the holidays.</p>
<p>In any case, being the good developer I am, after designing the core interfaces, I wrote some unit tests using JUnit 4.Â  Right click on the file in Package Explorer, hit "Run as JUnit Test" and it fires up in a fast view to show you how you did.Â  All very handy.Â  After a few tests, i figured I should build some test suites, but I really didn't want to.Â  I don't know about anyone else, but I always end up forgetting to register some test or another, and then I create a regression that would get caught by that test, but since it's not registered it doesn't run, and it's just bad.Â  So I didn't, and continued to run the tests individually.</p>
<p>After half an hour or so so, I had the idea to try right clicking on a package and see if I could run all the test in that package.Â  I was quite pleased to see that you can.Â  Same thing works at the source folder and project levels.Â  Little efficiency improvements like that make Barney a happy boy.Â  Of course, still have to write the suites if I want to run them from CI or the like, but this project at least will very likely never get there.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2008/11/06/eclipse-and-junit/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Java SE 1.6.0_10</title>
		<link>https://www.barneyb.com/barneyblog/2008/10/16/java-se-1_6_0_10/</link>
		<comments>https://www.barneyb.com/barneyblog/2008/10/16/java-se-1_6_0_10/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 16:49:50 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[coldfusion]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=528</guid>
		<description><![CDATA[Just did the 1.6.0_10 upgrade on my server.Â  Oh how I love Linux.Â  Just unarchved the new JDK, repointed a single symlink and restarted my Java servers.Â  There didn't seem to be a significant difference in spinup time for my ColdSpring AOP-heavy apps &#8211; perhaps a touch faster.Â  No problems with Magnolia either as near [...]]]></description>
			<content:encoded><![CDATA[<p>Just did the 1.6.0_10 upgrade on my server.Â  Oh how I love Linux.Â  Just unarchved the new JDK, repointed a single symlink and restarted my Java servers.Â  There didn't seem to be a significant difference in spinup time for my ColdSpring AOP-heavy apps &#8211; perhaps a touch faster.Â  No problems with Magnolia either as near as I've been able to tell.Â  WordPress, not surprisingly, was unaffected.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2008/10/16/java-se-1_6_0_10/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Even More Groovy</title>
		<link>https://www.barneyb.com/barneyblog/2008/09/24/even-more-groovy/</link>
		<comments>https://www.barneyb.com/barneyblog/2008/09/24/even-more-groovy/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 21:41:06 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=509</guid>
		<description><![CDATA[I have a confession to make.Â  My neat little code counter utility is partially a lie.Â  I wrote the entire thing as a single Groovy script, and only split it up into individual files for each class to release it.Â  271 lines of code (419 if you count the blank lines) simply does not justify [...]]]></description>
			<content:encoded><![CDATA[<p>I have a confession to make.Â  My neat little <a href="http://www.barneyb.com/barneyblog/2008/09/24/more-groovy-goodness/">code counter</a> utility is partially a lie.Â  I wrote the entire thing as a single Groovy script, and only split it up into individual files for each class to release it.Â  271 lines of code (419 if you count the blank lines) simply does <strong>not</strong> justify seven distinct files.Â  That said, it <strong>does</strong> justify a runner script and six distinct classes.Â  So if you want the "real" source, just take the six classes, copy them directly into Runner.groovy and then delete the files.Â  Everything works exactly the same, except it's all in one concise package.</p>
<p>The project started with a pile of procedural code (i.e. a Groovy script), all inline with no classes at all.Â  My basic concepts proved sound, and I started refactoring.Â  Does anyone NOT like refactoring?Â  If so, raise your hand so I'll know who to slap.Â  ;)Â  Classes quickly started falling out of the proof-of-concept code, and soon I had my four core classes (CodeCounter, ProjectInfo, PathInfo, and FileInfo), plus some no-longer-quite-functioning output code.</p>
<p>Once the "backend" was refactored into a stable model, the front-end went just the same.Â  XML was the format of the original script, and so I reimplemented the same output based on the model, rather than emitting it inline.Â  To ensure I wasn't being stupid and coupling where I shouldn't, I threw together the text renderer as well.</p>
<p>I'm a huge fan of this style of development, and do much the same thing with CF.Â  Start writing one big-ass file with no real concern for parameterization, abstraction, or encapsulation.Â  Once it works "enough", start refactoring for those three characteristics, as well as extending the functionality into something useful to the real world.</p>
<p>Doing Java is a bit harder, since you have the object nature foisted on you from the start.Â  You can still begin with one class and a pile of static methods, but the refactoring is a bit harder, I think, because of the static/dynamic transition.Â  With CF and Groovy, you pretty much bypass all of that (thank you compilers!), which is very nice.</p>
<p>What's the downside to this style of development?Â  Unit testing is hard.Â  With a rapidly evolving project (structurally), having to evolve unit tests can be a significant burden.Â  Not to mention that you can't really unit test a single large script; you're stuck waiting until you have an class which is after most of the work is done.Â  So if you write unit tests at all (I didn't), they have to come late in the cycle.</p>
<p>The main benefit is that you don't have to think about architecture before implementing functionality.Â  If you know exactly what your desired functionality is, and know how you're going to approach implementing it then architecture is the "hard" part, and unit tests can help ensure your implementation matches what you expect/require.Â  However, that's not the case a lot of time.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2008/09/24/even-more-groovy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CF Groovy Preso</title>
		<link>https://www.barneyb.com/barneyblog/2008/09/12/cf-groovy-preso/</link>
		<comments>https://www.barneyb.com/barneyblog/2008/09/12/cf-groovy-preso/#comments</comments>
		<pubDate>Sat, 13 Sep 2008 03:11:15 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=501</guid>
		<description><![CDATA[Last night I talked at the PDX RIA group about using Groovy to extend CFML applications and better leverage some of the benefits that Java has to offer (in addition to the benefits Groovy itself brings).Â  Unfortunately we had some technical difficulties, but the presentation was recorded on Connect, and can be accessed at http://experts.na3.acrobat.com/p71343823/.Â  [...]]]></description>
			<content:encoded><![CDATA[<p>Last night I talked at the PDX RIA group about using Groovy to extend CFML applications and better leverage some of the benefits that Java has to offer (in addition to the benefits Groovy itself brings).Â  Unfortunately we had some technical difficulties, but the presentation was recorded on Connect, and can be accessed at <a href="http://experts.na3.acrobat.com/p71343823/">http://experts.na3.acrobat.com/p71343823/</a>.Â  I apologize for the delay in posting, I usually try to get things up immediately afterward, but just didn't happen this time.</p>
<p>In addition to the Connect recording, I've posted <a href="http://www.barneyb.com/barneyblog/wp-content/uploads/2008/09/cfgroovy_preso_2008_09_11.pdf">my slides (in PDF format)</a>.Â  The sample app I demoed is just the CF Groovy demo app available at <a href="https://ssl.barneyb.com/svn/barneyb/cfgroovy/trunk/demo">https://ssl.barneyb.com/svn/barneyb/cfgroovy/trunk/demo</a>.Â  Within the demo app is the framework itself, including Hibernate (whose JARs are the source of the large download).Â  The demo app is also <a href="http://www.barneyb.com/cfgroovy/">available online</a> should you wish to run it without having to download anything.Â  Of course, there's not much to see without the code.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2008/09/12/cf-groovy-preso/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thread.setContextClassLoader Doesn&#039;t Work on CF 8.0.0</title>
		<link>https://www.barneyb.com/barneyblog/2008/07/10/threadsetcontextclassloader-doesnt-work-on-cf-800/</link>
		<comments>https://www.barneyb.com/barneyblog/2008/07/10/threadsetcontextclassloader-doesnt-work-on-cf-800/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 20:53:56 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[coldfusion]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=439</guid>
		<description><![CDATA[I know the number of CF 8.0.0 installs is probably pretty minimal compared to CF 8.0.1, but thought this was worth pointing out.Â  If you use Thread.setContextClassLoader on CF 8.0.0, it raises no exception, but it doesn't actually set the ClassLoader for the thread.
I ran into this today using my CF Groovy/Hibernate integration on one [...]]]></description>
			<content:encoded><![CDATA[<p>I know the number of CF 8.0.0 installs is probably pretty minimal compared to CF 8.0.1, but thought this was worth pointing out.Â  If you use Thread.setContextClassLoader on CF 8.0.0, it raises no exception, but it doesn't actually set the ClassLoader for the thread.</p>
<p>I ran into this today using my CF Groovy/Hibernate integration on one of my existing CF installs that is still 8.0.0.Â  It totally bombs, because the classloading trickery fails if it can't set up a classloader.Â  After spending a bunch of time on it, I just gave up, as nothing I tried had any effect.</p>
<p>Both CF 8.0.1 and Railo 3.0b2 correctly allow overriding the context ClassLoader, and can therefore use the Hibernate via CF Groovy.Â  I haven't tried in a while, but OBD exhibited similar symptoms as CF 8.0.0 when trying to run Hibernate, so it may suffer from the same problem.Â  This only affects the Hibernate stuff I'm doing, the base Groovy integration requires no ClassLoader trickery, so it works on all four without issue (and probably CF 7 too).</p>
<p>I should also note that this is NOT the underlying JVM.Â  I use the same JVM (a 1.6 series from Sun) for all my stuff, both development and production.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2008/07/10/threadsetcontextclassloader-doesnt-work-on-cf-800/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun with Classloading in Java</title>
		<link>https://www.barneyb.com/barneyblog/2008/07/04/fun-with-classloading-in-java/</link>
		<comments>https://www.barneyb.com/barneyblog/2008/07/04/fun-with-classloading-in-java/#comments</comments>
		<pubDate>Sat, 05 Jul 2008 06:45:58 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=435</guid>
		<description><![CDATA[With my CF Groovy project, I've been doing a lot of Java coding of late.  It's all been written in CFML, but it's mostly Java code in CFML syntax.  As an aside, doing that sucks.  CFML is horrible for writing anything more than the simplest Java code.  But on to the [...]]]></description>
			<content:encoded><![CDATA[<p>With my <a href="http://www.barneyb.com/barneyblog/projects/cf-groovy/">CF Groovy</a> project, I've been doing a lot of Java coding of late.  It's all been written in CFML, but it's mostly Java code in CFML syntax.  As an aside, doing that sucks.  CFML is horrible for writing anything more than the simplest Java code.  But on to the topic at hand&#8230;.</p>
<p>To this point in my career, basically all of the Java code I've written has been application code.  Most of the CFML, JavaScript, and ActionScript I write is also application code, but I've contributed significantly to Fusebox and built a number of micro-frameworks in all three languages.  However, none of that touches on the stuff I've done in the past couple weeks.  The primary source of my issues getting <a href="http://groovy.codehaus.org/">Groovy</a> and <a href="http://www.hibernate.org/">Hibernate</a> to play together was classloading.</p>
<p>Unlike <a href="http://grails.org/">Grails</a> (GORM, really), any of the various examples on the web, and I'm guessing <a href="http://www.firemoss.com/blog/index.cfm/Hiberailooving">Joe Rinehart's Hiberailooving</a> project, three of the inviolate framework objectives were zero dependency on an IDE beyond text editing, no manual compilation, and no container restarts.  Obviously, Hibernate provides a set of IDE tooling that can be brought to bear, but I'm talking about just the CF integration portion.  I want to be productive with emacs and a web browser.</p>
<p>This presented a number of issues with classloading, because Groovy can only be loaded by the GroovyClassLoader (and subclasses).  Basically this forced my hand to using compiled Groovy code, and ensuring it and Hibernate are loaded by the same ClassLoader.  No GroovyClassLoader at all.</p>
<p>Now all that's well and good, but you have to be a bit careful, because two of the goals where no manual compilation and no container restarts.  Doing compilation from CF is fairly simple (instantiate FileSystemCompiler and call 'main' with the right args), though again, getting all the right stuff on the classpath in the right order proved a nightmare.  This is further complicated by the while JEE classloader situation, which isn't straightforward at all.</p>
<p>The details of this intricate dance completely escaped me for a week and a half.  Then one night, while lying in bed, it all clicked together (thank you, Heather, for going to England).  The solutions seem fairly obvious now, but they took a lot of fussing and fighting to deduce.  I'd never even instantiated a ClassLoader before, aside from a couple one-off URLClassLoaders in CFML to lazy-load some JARs.  Now I've got stacks of ClassLoaders, in some places two or three deep.</p>
<p>After my initial post-epiphany implementation was complete, I realized I can do some streamlining, but that's for after the release.  I think I can even remove the need to drop the Groovy JAR in your /WEB-INF/lib folder, without adding any code complexity or runtime overhead, which would a nice bonus for ease of deployment.  I.e., unzip the engine, write an entity, save it to the DB.  No JARs, no restart the container, nothing.</p>
<p>It's been a very interesting (and pleasurable) experience, since it's so different from my day job of banging out boring little presentation apps all day.  I've learned a lot, and even just the past few days of thinking about how other Java apps/frameworks work, I've realized how applicable that knowledge really is.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2008/07/04/fun-with-classloading-in-java/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CF Groovy Takes a Nap</title>
		<link>https://www.barneyb.com/barneyblog/2008/07/02/cf-groovy-takes-a-nap/</link>
		<comments>https://www.barneyb.com/barneyblog/2008/07/02/cf-groovy-takes-a-nap/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 00:35:40 +0000</pubDate>
		<dc:creator>barneyb</dc:creator>
				<category><![CDATA[cfml]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[railo]]></category>

		<guid isPermaLink="false">http://www.barneyb.com/barneyblog/?p=433</guid>
		<description><![CDATA[After close to two weeks of struggling, I finally managed to deploy pure source to a CFML runtime (Railo, in this case), and get Groovy entities in and out of the database with Hibernate.Â  No compliation, no IDE, no development-mode server, just my Groovy source along with a hacked up CF Groovy.Â  This is very [...]]]></description>
			<content:encoded><![CDATA[<p>After close to two weeks of struggling, I finally managed to deploy pure source to a CFML runtime (<a href="http://www.railo.ch/">Railo</a>, in this case), and get <a href="http://groovy.codehaus.org/">Groovy</a> entities in and out of the database with <a href="http://www.hibernate.org/">Hibernate</a>.Â  No compliation, no IDE, no development-mode server, just my Groovy source along with a hacked up <a href="http://www.barneyb.com/barneyblog/projects/cf-groovy/">CF Groovy</a>.Â  This is very exciting for me, because while Groovy is cool and all, CF's dynamic nature has become a must have.</p>
<p>I don't have source to download yet, just a horribly hacky proof of concept, but here's what the user of the "framework" does.Â  First, create your entity:</p>
<pre>package com.barneyb
import javax.persistence.*

@Entity
class Person {

  @Id
  @GeneratedValue
  Long id
  Long version
  String name
  Date dob

  def getAgeInSeconds() {
    (new Date().getTime() - dob.getTime()) / 1000
  }

  def getAgeInDays() {
    ageInSeconds / 86400
  }

  def getAgeInYears() {
    ageInDays / 365.249
  }

  String toString() {
    "$name is $ageInYears years ($ageInDays days) old"
  }

}
</pre>
<p>That's the same class as my initial CF Groovy demo used, except with the of JPA annotations added.Â  Because I'm binding to Hibernate, you can use any Hibernate-supported annotations, but I opted to stick with vanilla JPA.Â  Now we need our hibernate.cfg.xml, which is totally stock:</p>
<pre>&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD//EN"
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"&gt;
&lt;hibernate-configuration&gt;

  &lt;session-factory&gt;

    &lt;property name="current_session_context_class"&gt;thread&lt;/property&gt;
    &lt;property name="cache.provider_class"&gt;org.hibernate.cache.NoCacheProvider&lt;/property&gt;
    &lt;property name="show_sql"&gt;true&lt;/property&gt;
    &lt;property name="hibernate.dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/property&gt;
    &lt;property name="hibernate.connection.driver_class"&gt;com.mysql.jdbc.Driver&lt;/property&gt;
    &lt;property name="hibernate.connection.url"&gt;jdbc:mysql://localhost:3306/dbname&lt;/property&gt;
    &lt;property name="hibernate.connection.username"&gt;username&lt;/property&gt;
    &lt;property name="hibernate.connection.password"&gt;password&lt;/property&gt;
    &lt;property name="hibernate.hbm2ddl.auto"&gt;update&lt;/property&gt;

    &lt;mapping class="com.barneyb.Person" /&gt;

  &lt;/session-factory&gt;

&lt;/hibernate-configuration&gt;
</pre>
<p>You could also map your classes manually with XML, if you wanted, but for the sake of simplicitly, I've done it all with annotations.Â  You'll also notice the database connection information embedded directly in the file. This is far from ideal.Â  I'm hoping to extract it from a CFML DSN, but that might only be possible on Adobe ColdFusion (via the Admin API).Â  The last thing is the test script:</p>
<pre>&lt;g:script&gt;
  import java.text.SimpleDateFormat

  import org.hibernate.*
  import org.hibernate.cfg.*

  import com.barneyb.Person

  sdf = new java.text.SimpleDateFormat("yyy/MM/dd")
  sdf.lenient = true

  def sf = new AnnotationConfiguration()
      .configure().buildSessionFactory()
  def sess = sf.openSession()
  def tx  = sess.beginTransaction()
  sess.createQuery("delete Person").executeUpdate()
  sess.save(new Person(
    name: attributes.name ?: "Barney",
    dob: sdf.parse(attributes.dob ?: "1980/06/10")
  ))
  tx.commit()
  sess.close()
  sf.close()
&lt;/g:script&gt;</pre>
<p>No need to compile anything, no need to drop JARs all over your server, nothing.Â  Write, refresh, persist.Â  That includes adding new entities, new properties to existing entities, etc.</p>
<p>It's not ready for public consumption at the moment, but that's my top "free time" priority.Â  For the incredibly impatient, there's a <a href="https://ssl.barneyb.com/svn/barneyb/cfgroovy/branches/hibernate/">branch in my SVN repository</a> with the current source.Â  Don't expect anything pretty.Â  ;)</p>
]]></content:encoded>
			<wfw:commentRss>https://www.barneyb.com/barneyblog/2008/07/02/cf-groovy-takes-a-nap/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
