uPortal IRC Logs-2009-04-03

[08:31:59 EDT(-0400)] * lennard1 (n=sparhk@ip68-98-56-21.ph.ph.cox.net) has left ##uportal
[08:37:37 EDT(-0400)] * dstn (n=dstn@unaffiliated/dstn) has joined ##uportal
[08:47:50 EDT(-0400)] * michelled (n=michelle@CPE001310472ade-CM0011aefd3ca8.cpe.net.cable.rogers.com) has joined ##uportal
[08:51:51 EDT(-0400)] * lennard1 (n=sparhk@wsip-98-174-242-39.ph.ph.cox.net) has joined ##uportal
[08:53:12 EDT(-0400)] * athena (n=athena@128.36.158.162) has joined ##uportal
[08:55:32 EDT(-0400)] * athena (n=athena@dhcp128036158162.central.yale.edu) has joined ##uportal
[09:10:10 EDT(-0400)] * fj4000 (n=Main@CPE0018f85ab63e-CM001692f5798c.cpe.net.cable.rogers.com) has joined ##uportal
[09:12:37 EDT(-0400)] * colinclark (n=colin@bas2-toronto09-1176130727.dsl.bell.ca) has joined ##uportal
[09:54:50 EDT(-0400)] * EricDalquist (n=dalquist@bohemia.doit.wisc.edu) has joined ##uportal
[09:59:17 EDT(-0400)] * bszabo_ (n=bszabo@wsip-98-174-242-39.ph.ph.cox.net) has joined ##uportal
[10:58:35 EDT(-0400)] * jessm (n=Jess@c-71-232-3-4.hsd1.ma.comcast.net) has joined ##uportal
[11:00:01 EDT(-0400)] <dstn> EricDalquist, any plans to release the ajax support?
[11:05:24 EDT(-0400)] <EricDalquist> um sure (smile)
[11:05:31 EDT(-0400)] <EricDalquist> you have anything you'd like fixed in it first?
[11:05:41 EDT(-0400)] <EricDalquist> or would you like to take it over?
[11:13:29 EDT(-0400)] * athena (n=athena@dhcp128036007188.central.yale.edu) has joined ##uportal
[11:15:24 EDT(-0400)] * awills (n=awills@wsip-98-174-242-39.ph.ph.cox.net) has joined ##uportal
[11:17:19 EDT(-0400)] * michelled (n=team@142.150.154.193) has joined ##uportal
[11:23:25 EDT(-0400)] <athena> i think it would be nice to add the ProxyView to the ajax support project
[11:23:32 EDT(-0400)] <athena> although that code needs some cleanup
[11:23:38 EDT(-0400)] <athena> i don't know if anyone would have time to look at that?
[11:32:39 EDT(-0400)] * colinclark (n=colin@142.150.154.101) has joined ##uportal
[11:34:24 EDT(-0400)] * holdorph (n=holdorph@wsip-98-174-242-39.ph.ph.cox.net) has joined ##uportal
[13:26:25 EDT(-0400)] * Sememmon (n=Sememmon@uni1.unicon.net) has joined ##uportal
[13:38:09 EDT(-0400)] * athena (n=athena@dhcp128036159099.central.yale.edu) has joined ##uportal
[14:04:43 EDT(-0400)] <EricDalquist> anyone know of an in-memory HTTP server that can be used for unit testing?
[14:04:50 EDT(-0400)] <EricDalquist> something like HSQLDB for HTTP
[14:14:28 EDT(-0400)] <bszabo_> jetty
[14:14:54 EDT(-0400)] <bszabo_> actually, sorry, I don't think it has "in-memory" only
[14:15:47 EDT(-0400)] <bszabo_> will require socket connections
[14:15:59 EDT(-0400)] <bszabo_> what are you trying to test?
[14:17:40 EDT(-0400)] <EricDalquist> some code that uses HttpClient
[14:17:44 EDT(-0400)] <EricDalquist> but I can't easily mock that
[14:18:24 EDT(-0400)] <bszabo_> we separate unit tests from integration tests so that intensive tests like hitting a local Jetty or SoapUI WS server, or even hitting the in-memory HSQLDB don't have to slow down devs who really just want unit tests as the first step
[14:18:31 EDT(-0400)] * colinclark (n=colin@142.150.154.101) has joined ##uportal
[14:19:10 EDT(-0400)] <bszabo_> I would look to use Jetty in that case
[14:19:15 EDT(-0400)] <EricDalquist> brb
[14:19:24 EDT(-0400)] <bszabo_> maven-jetty-plugin or something custom
[14:54:42 EDT(-0400)] * athena (n=athena@99.129.100.66) has joined ##uportal
[15:56:01 EDT(-0400)] * michelled (n=team@142.150.154.193) has left ##uportal
[17:00:08 EDT(-0400)] <awills> still there EricDalquist?
[17:00:13 EDT(-0400)] <EricDalquist> yup
[17:00:22 EDT(-0400)] <awills> finally got mu ducks in a row: http://www.ja-sig.org/issues/browse/UP-2406
[17:00:27 EDT(-0400)] <awills> my*
[17:01:08 EDT(-0400)] <awills> do you perhaps have a few minutes to note the scope of the patch?
[17:01:26 EDT(-0400)] <EricDalquist> 101k ... fun (big grin)
[17:01:31 EDT(-0400)] <awills> lol
[17:01:58 EDT(-0400)] <awills> so... going into this I was convinced this was the "right thing to do"
[17:02:09 EDT(-0400)] <awills> if anything, i'm even more convinced now (wink)
[17:02:41 EDT(-0400)] <EricDalquist> well I'm applying the patch locally
[17:02:51 EDT(-0400)] <EricDalquist> I'll try and spend some time in the next 30 minutes or so looking at it
[17:03:06 EDT(-0400)] <awills> but i my sense is that this is 3.2 material... i'm concerned about the possibility of risk to the rel-3-1-patches branch
[17:04:16 EDT(-0400)] <awills> i think there will be some follow-on, and i don't want to put rel-3-1-patches in a state where we would be anxious about cutting 3-1-1 on a dime, should there be a security patch or somesuch
[17:05:05 EDT(-0400)] <awills> it occurs to me that we can advise folks who really want these enhancements to use a proto-3-2 to upgrade, then run their portal on 3.1
[17:05:20 EDT(-0400)] <awills> and in fact this is something i'm going to take up with yale
[17:06:40 EDT(-0400)] <awills> besides, i'm being told by smart people that it might be better for us to cut minor releases a bit more frequently... so it might be nice to cut a 3.2 in a couple/3 mo. anyway
[17:06:51 EDT(-0400)] <athena> awills: for the record, i don't think the current proposal will allow for multi-profile support
[17:07:07 EDT(-0400)] <awills> the current patch you mean?
[17:07:26 EDT(-0400)] <athena> well, what seems to be outlined in the linked wiki doc
[17:07:37 EDT(-0400)] <athena> have yet to look at the patch - i'd like to, but leaving for the airport in a bit
[17:07:59 EDT(-0400)] <awills> some changes are required for multi-profile support, and this is part of it
[17:08:13 EDT(-0400)] <awills> airport?
[17:08:30 EDT(-0400)] <athena> yeah, disappearing for the weekend
[17:08:39 EDT(-0400)] <holdorph> poof
[17:08:42 EDT(-0400)] <awills> ah, good for you
[17:08:45 EDT(-0400)] <awills> lol
[17:08:46 EDT(-0400)] <athena> i hope so :/
[17:08:53 EDT(-0400)] <athena> sounds like the philly airport is a mess right now
[17:09:08 EDT(-0400)] <athena> and my connection is the last flight of the day . . .
[17:09:09 EDT(-0400)] * awills doesn't like the philly airport much
[17:09:35 EDT(-0400)] <athena> i don't at all - especially for puddle jumper flights
[17:09:37 EDT(-0400)] <athena> it's always a mess
[17:09:57 EDT(-0400)] <awills> i'm always there at the same time of day, and there's always no room anywhere
[17:10:04 EDT(-0400)] * athena will be very heartbroken if she misses her connection
[17:10:06 EDT(-0400)] <awills> around dinner time
[17:11:10 EDT(-0400)] <athena> got an alert saying flights are up to 90 min late, and my connection is like an hour :/
[17:11:28 EDT(-0400)] <athena> hopefully it'll smooth out
[17:11:31 EDT(-0400)] <awills> nice
[17:11:33 EDT(-0400)] <athena> anyway, about profiles.
[17:11:43 EDT(-0400)] <awills> couldn't you just drive to philly? :/
[17:11:50 EDT(-0400)] <athena> hm, probably
[17:12:13 EDT(-0400)] <athena> though wouldn't likely get there in time to check in, given NYC traffic
[17:12:24 EDT(-0400)] <athena> the reason i said something was because of "If we create a separate .profile document, we can at least support multiple profiles (using a single layout). This enhancement is probably all that's needed for Import/Export to support portals with an additional theme for mobile devices.
[17:13:10 EDT(-0400)] <athena> i don't think multiple profiles will work with import/export until we fix the code to no longer rely on profile ID numbers
[17:13:21 EDT(-0400)] <awills> yeah i worded that stuff too strongly when i first created the wiki page
[17:13:37 EDT(-0400)] <awills> haven't gone back to correct it, though we've spoken about it since
[17:14:39 EDT(-0400)] <athena> ah ok
[17:14:42 EDT(-0400)] <athena> good deal (smile)
[17:15:00 EDT(-0400)] <athena> that said, this will be a great step towards getting that working
[17:16:21 EDT(-0400)] <awills> yeah, for profiles: (1) there's no good way to get the right data in, and (2) there are some issues with how the Java code responds to the "right data" too
[17:16:39 EDT(-0400)] <awills> this step will get us almost to (1)
[17:17:41 EDT(-0400)] <athena> and (3) Java doesn't create the right data for new users either
[17:18:51 EDT(-0400)] <awills> ah ok, that's what I was trying to say w/ (2)
[17:19:09 EDT(-0400)] <awills> but i guess there's more than that
[17:27:17 EDT(-0400)] <awills> old export-layout.crn is 252 lines, new one is just this: http://uportal.pastebin.com/d6ae7ae80
[17:28:42 EDT(-0400)] <awills> new import for layouts is 40 lines: http://uportal.pastebin.com/d5558b18a
[17:29:21 EDT(-0400)] <athena> nice (smile)
[17:29:31 EDT(-0400)] <athena> so to add a new user, we'll add user, layout, and profile files?
[17:29:46 EDT(-0400)] <awills> yeah, i hope that's cool
[17:30:01 EDT(-0400)] <awills> but you don't need layout/profile, i don't think
[17:30:10 EDT(-0400)] <awills> if there's nothing special about them
[17:30:30 EDT(-0400)] <athena> that makes sense
[17:30:37 EDT(-0400)] <athena> so really only if you want to specify a layout
[17:30:47 EDT(-0400)] <awills> yeah
[17:31:03 EDT(-0400)] <EricDalquist> ok ... just finished my integration test
[17:31:06 EDT(-0400)] <EricDalquist> I'll go look at the patch now
[17:31:15 EDT(-0400)] <EricDalquist> I was thinking the other day ... do we actually need .user files?
[17:33:18 EDT(-0400)] <awills> yeah maybe not
[17:33:36 EDT(-0400)] <EricDalquist> we could have the other types that need a UP_USER entry just lazily create one when needed
[17:34:00 EDT(-0400)] <EricDalquist> there isn't anything of value in those files other than default template user ID
[17:34:06 EDT(-0400)] <awills> we could continue to support .user files, in case someone's using multiple template users
[17:34:11 EDT(-0400)] <EricDalquist> yeah
[17:34:24 EDT(-0400)] <EricDalquist> I'm hoping that isn't going to be very common in 3.x
[17:34:42 EDT(-0400)] <awills> oh me too (smile)
[17:35:49 EDT(-0400)] <EricDalquist> comments on the code so far:
[17:36:06 EDT(-0400)] <EricDalquist> can 'get-layout-store.crn' be a real Java class instead of CRN code?
[17:36:19 EDT(-0400)] <EricDalquist> My fear of CRN scripts is brittleness, we don't get compile time checks there
[17:36:36 EDT(-0400)] <EricDalquist> and that seems like it should extend Springs BeanFactory ...
[17:36:39 EDT(-0400)] <awills> yeah, i think that's good... and it can be a class that we pass to the task w/ DI
[17:37:13 EDT(-0400)] <EricDalquist> er ... FactoryBean
[17:37:36 EDT(-0400)] <awills> get-layout-store.crn was an evasive maneuver... when i discovered i couldn't wire a live RDBMDisLaySt
[17:37:43 EDT(-0400)] <EricDalquist> take a look at AbstractFactoryBean
[17:38:30 EDT(-0400)] <EricDalquist> if that is causing eager-init problems we can wrap it in a LazyInitTargetSource
[17:40:42 EDT(-0400)] <EricDalquist> brb
[17:41:06 EDT(-0400)] * EricDalquist (n=dalquist@bohemia.doit.wisc.edu) has joined ##uportal
[17:42:07 EDT(-0400)] <awills> wb
[17:42:13 EDT(-0400)] <EricDalquist> I don't think the lazy loading of the system person in RDBMUserLayoutStore is thread safe (double checked locking pattern w/synchronized block)
[17:42:30 EDT(-0400)] <EricDalquist> take a look at SingletonDoubleCheckedCreator
[17:42:35 EDT(-0400)] <EricDalquist> in org.jasig.portal.utils.threading]
[17:42:59 EDT(-0400)] <awills> it should be thread safe using a synchonized method
[17:43:03 EDT(-0400)] <EricDalquist> nope
[17:43:11 EDT(-0400)] <EricDalquist> same as just doing synch(this)
[17:43:17 EDT(-0400)] <EricDalquist> the JIT may inline that method
[17:43:23 EDT(-0400)] <EricDalquist> so doing:
[17:43:33 EDT(-0400)]

<EricDalquist> if (a == null)

Unknown macro: { initA() }

[17:43:41 EDT(-0400)] <EricDalquist> could be the same as
[17:43:42 EDT(-0400)] <awills> i thought synch methods were ok... if not, how do you ever make something like that tread safe?
[17:43:48 EDT(-0400)] <EricDalquist> you don't
[17:44:05 EDT(-0400)] <EricDalquist> if you use Sync you have to wrap the check too
[17:44:08 EDT(-0400)] <EricDalquist> the outermost check
[17:44:10 EDT(-0400)] <EricDalquist> or
[17:44:15 EDT(-0400)] <EricDalquist> you use the new concurrent APIs
[17:44:31 EDT(-0400)] <EricDalquist> read/write locks let you do double-checked initialization that is safe
[17:45:23 EDT(-0400)] <EricDalquist> so the patch looks good to me other than those two changes.
[17:46:04 EDT(-0400)] <awills> what would be the consequence of a collision? looks like just setting the local variable twice, not something like corrupting a map
[17:46:18 EDT(-0400)] <awills> good
[17:46:47 EDT(-0400)] <EricDalquist> true
[17:46:53 EDT(-0400)] <EricDalquist> in this case it would just run the init code twice
[17:47:10 EDT(-0400)] <EricDalquist> but it would be better not not have code that looks like it does one thing but could do another in the project
[17:47:24 EDT(-0400)] <awills> yeah true
[17:47:39 EDT(-0400)] <EricDalquist> or at least explicitly document that this falls into the double-checked-locking anti-pattern
[17:47:47 EDT(-0400)] <EricDalquist> and the consequences of such
[17:48:03 EDT(-0400)] <EricDalquist> the SingletonDoubleCheckedCreator will do what you want
[17:48:08 EDT(-0400)] <EricDalquist> and should be easy to drop in
[17:48:39 EDT(-0400)] <EricDalquist> its as easy to use as:
[17:48:40 EDT(-0400)] <EricDalquist> private static final SingletonDoubleCheckedCreator<EntityCachingService> instanceHolder = new SingletonDoubleCheckedCreator<EntityCachingService>() {
[17:48:40 EDT(-0400)] <EricDalquist> @Override
[17:48:40 EDT(-0400)] <EricDalquist> protected EntityCachingService createSingleton(Object... args) {
[17:48:40 EDT(-0400)] <EricDalquist> return new EntityCachingService();
[17:48:41 EDT(-0400)] <EricDalquist> }
[17:48:43 EDT(-0400)] <EricDalquist> };
[17:49:03 EDT(-0400)] <EricDalquist> the client code just does "EntityCachingService cacheService = instanceHolder.get();"
[17:49:26 EDT(-0400)] <EricDalquist> if you want to can pass arguments into the get() that show up in the createSingleton call
[17:58:28 EDT(-0400)] <awills> the online resources I can fins seem to suggest that this example would be threadsafe: http://uportal.pastebin.com/d5b86d625
[17:58:43 EDT(-0400)] <awills> http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
[17:58:45 EDT(-0400)] <awills> and others
[17:59:18 EDT(-0400)] <EricDalquist> yes
[17:59:24 EDT(-0400)] <EricDalquist> notice there is only a single if
[17:59:35 EDT(-0400)] <EricDalquist> the problem is you have the outer if
[17:59:39 EDT(-0400)] <EricDalquist> then the inner if
[18:00:25 EDT(-0400)] <awills> but the inner if is surrounded by a full synchronized method
[18:00:32 EDT(-0400)] <awills> like the example
[18:00:55 EDT(-0400)] <EricDalquist> right ... just a sec
[18:01:01 EDT(-0400)] <EricDalquist> let me go find the reasoning why it is bad
[18:01:49 EDT(-0400)] <EricDalquist> http://www.ibm.com/developerworks/java/library/j-dcl.html
[18:02:11 EDT(-0400)] <awills> this debate seems to get worse steadily with time :/ things that were ok 7 years ago became bad 4 years ago... things that were ok then became bad more recently
[18:02:41 EDT(-0400)] <EricDalquist> double checked locking has always been bad
[18:02:54 EDT(-0400)] <EricDalquist> it has always been a reality of the java memory model
[18:04:24 EDT(-0400)] <awills> The bottom line is that double-checked locking, in whatever form, should not be used because you cannot guarantee that it will work on any JVM implementation. JSR-133 is addressing issues regarding the memory model, however, double-checked locking will not be supported by the new memory model. Therefore, you have two options: Accept the synchronization of a getInstance() method as shown in Listing 2. [...]
[18:04:24 EDT(-0400)] <EricDalquist> the result in this case, as you stated, could be two SystemUser objects being created instead of just one
[18:04:32 EDT(-0400)] <EricDalquist> which likely isn't bad
[18:04:34 EDT(-0400)] <EricDalquist> but could be
[18:04:55 EDT(-0400)] <EricDalquist> because existing code could in theory do sysUser2 == sysUser1
[18:04:57 EDT(-0400)] <EricDalquist> and work right now
[18:05:13 EDT(-0400)] <EricDalquist> or do other things with sysUser that assume there is only one
[18:05:14 EDT(-0400)] <awills> i'm already happy to change it, if just to avoid having to discuss it again in the future (wink)
[18:05:18 EDT(-0400)] <EricDalquist> lol
[18:05:40 EDT(-0400)] <awills> what about that quote though? it's from your acticle
[18:06:06 EDT(-0400)] <EricDalquist> right
[18:06:10 EDT(-0400)] <EricDalquist> so you sync the whole method
[18:06:16 EDT(-0400)] <awills> i did (smile)
[18:06:19 EDT(-0400)] <EricDalquist> yes
[18:06:24 EDT(-0400)] <EricDalquist> but you are also doing a check before you call it
[18:06:29 EDT(-0400)] <EricDalquist> remember java inlines code
[18:06:45 EDT(-0400)] <holdorph> you didn't synchronize getSystemUser() if i'm all caught up and talking about the right thing
[18:06:48 EDT(-0400)] <EricDalquist> the compiler will see that the syncd method will never get called anywhere other than from the one place it does
[18:06:52 EDT(-0400)] <holdorph> only the initSystemUser() method
[18:06:56 EDT(-0400)] <EricDalquist> so that method goes away
[18:07:02 EDT(-0400)] <EricDalquist> and gets inlined into your outer if
[18:07:40 EDT(-0400)] <EricDalquist> http://uportal.pastebin.com/d653d6e03
[18:07:42 EDT(-0400)] <EricDalquist> that is the code right now
[18:07:47 EDT(-0400)] <awills> that's no good... that's a change in behavior
[18:08:03 EDT(-0400)] <EricDalquist> that is what the Java language contract states it can do
[18:08:08 EDT(-0400)] <EricDalquist> and exactly why DCL is broken
[18:08:14 EDT(-0400)] <EricDalquist> no matter how round-about you want to try
[18:08:57 EDT(-0400)] <EricDalquist> http://uportal.pastebin.com/d7d6f2269
[18:09:03 EDT(-0400)] <EricDalquist> those two are exactly the same functionally
[18:09:19 EDT(-0400)] <EricDalquist> and the second is much more likely as to how the code will be executed
[18:09:29 EDT(-0400)] <awills> yeah that would be no good
[18:09:34 EDT(-0400)] <EricDalquist> even if #1 is how it is done
[18:09:45 EDT(-0400)] <EricDalquist> the extra method call doesn't cause memory write sync
[18:09:47 EDT(-0400)] <awills> the whole point of #1 is that it's not #2
[18:09:50 EDT(-0400)] <EricDalquist> which is what is needed to solve the problem
[18:10:04 EDT(-0400)] <EricDalquist> even if it isn't inlined like #2
[18:10:10 EDT(-0400)] <EricDalquist> functionally it is the same
[18:10:27 EDT(-0400)] <EricDalquist> the Java memory model is such that until you do a sync() one thread may not see another threads memory changes
[18:10:37 EDT(-0400)] <EricDalquist> so even with that method call in there
[18:10:42 EDT(-0400)] <EricDalquist> it doesn't change anything
[18:11:03 EDT(-0400)] <EricDalquist> since a sync in the method is exactly the same as a sync(this) {} inside the method
[18:12:04 EDT(-0400)] <awills> article seems to imply this might do it: http://uportal.pastebin.com/d2851b51a
[18:12:19 EDT(-0400)] <EricDalquist> that would
[18:12:33 EDT(-0400)] <EricDalquist> actually no it wouldn't
[18:12:38 EDT(-0400)] <EricDalquist> you would have to make the method static
[18:12:45 EDT(-0400)] <EricDalquist> which wouldn't work because dataSource isn't static
[18:12:51 EDT(-0400)] <awills> oh yes, had that in my head to do and forgot
[18:12:58 EDT(-0400)] <EricDalquist> and static initializers == bad
[18:13:11 EDT(-0400)] <EricDalquist> that's why GAPs causes so much trouble with the Spring context in uPortal
[18:13:13 EDT(-0400)] * holdorph loathes static / class level initialization
[18:13:20 EDT(-0400)] * EricDalquist is with holdorph
[18:13:30 EDT(-0400)] <holdorph> talk about a major freaking PITA to debug
[18:14:12 EDT(-0400)] <awills> iirc, you can get CNFE when your static inits fail
[18:14:37 EDT(-0400)] <holdorph> that's one of many of the not-very-intuitive problems, yes
[18:16:08 EDT(-0400)] <EricDalquist> so here is the fix
[18:16:35 EDT(-0400)] <EricDalquist> http://uportal.pastebin.com/m56a920a3
[18:16:50 EDT(-0400)] <EricDalquist> SingletonDoubleCheckedCreator uses the concurrent Read/Write lock APIs
[18:17:04 EDT(-0400)] <EricDalquist> it lazily creates the system IPerson object when it is first requested
[18:17:20 EDT(-0400)] <EricDalquist> is faster than just a synchronized getSystemUser() method
[18:17:26 EDT(-0400)] <EricDalquist> and doesn't fall into the DLC problem
[18:17:45 EDT(-0400)] <EricDalquist> because the concurrent Read/Write lock APIs have memory consistency guarantees around them
[18:18:58 EDT(-0400)] <EricDalquist> http://uportal.pastebin.com/m559b74ed
[18:19:03 EDT(-0400)] <EricDalquist> that would work too and be safer
[18:19:11 EDT(-0400)] <EricDalquist> because it deletes initSystemUser
[18:19:20 EDT(-0400)] <EricDalquist> so there is no way to create more than one system user
[18:21:19 EDT(-0400)] <EricDalquist> the R/W lock docks actually give an example of double-checked-locking: http://java.sun.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html
[18:22:31 EDT(-0400)] <awills> the one with volatile boolean cacheValid; ?
[18:23:19 EDT(-0400)] <EricDalquist> yeah
[18:24:05 EDT(-0400)] <EricDalquist> I believe the cacheValid is volatile there because it can be modified outside of processCachedData()
[18:26:29 EDT(-0400)] <EricDalquist> got to run
[18:27:56 EDT(-0400)] <awills> yeah the online sources seemed to be saying the variable should be volitile anyway
[18:28:28 EDT(-0400)] <awills> post JSR-133 writeup: http://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html#dcl
[18:47:58 EDT(-0400)] * lennard1 (n=sparhk@wsip-98-174-242-39.ph.ph.cox.net) has joined ##uportal
[20:35:29 EDT(-0400)] * lennard1 (n=sparhk@wsip-98-174-242-39.ph.ph.cox.net) has left ##uportal
[20:46:13 EDT(-0400)] * colinclark (n=colin@bas2-toronto09-1176130727.dsl.bell.ca) has joined ##uportal
[20:48:25 EDT(-0400)] * awills (n=awills@wsip-98-174-242-39.ph.ph.cox.net) has left ##uportal