Woohoo!

I just tried the following change based on your suggestion that I explicitly
look at the current thread's context class loader:
#old version:
#Java.java.lang.Class.forName(dep.class).asSubclass(Java.java.lang.Class.forName(dep.subclass))

#new version:
Java.java.lang.Class.forName(dep.class, true,
Java.java.lang.Thread.currentThread().getContextClassLoader()).asSubclass(Java.java.lang.Class.forName(dep.subclass))

And the ugly little guy works just great. (whiskey tango foxtrot, but hey)

--Ed

On Tue, Nov 30, 2010 at 1:32 PM, Ed Smiley <[email protected]> wrote:

> No I haven't.  I'll give it a whirl.
>
>
> On Tue, Nov 30, 2010 at 1:24 PM, Alex Boisvert <[email protected]>wrote:
>
>> Have you tried this?
>>
>> Class.forName("com.mypackage.SomeImpl", true,
>> Thread.currentThread().getContextClassLoader())
>>
>> alex
>>
>> On Tue, Nov 30, 2010 at 11:51 AM, Ed Smiley <[email protected]> wrote:
>>
>> > First I will explain what I am doing.  (And which used to work.)
>> > If this confuses you, you can skip down below to read the details of the
>> > problem.  That's in section 2.
>> >
>> > I include this information only because it is an order of complexity
>> more
>> > complicated than most of the build programs that I have heard discussed.
>> >  So
>> > the answer "no problem, just rewrite everything" makes me, well, a bit
>> > nervous. :)
>> >
>> > 1.The background is that I have a main application consisting of a
>> number
>> > of
>> > jars and wars with its own build system, and jar classloader.  I then
>> have
>> > a
>> > build system that uses Buildr to create one or more jars which contain
>> > configurations and/or Java code and which are deployed to the main
>> > application. The main application knows how to introspect all the jar
>> files
>> > at startup, so this is highly extensible.
>> >
>> > If they contain only configurations, they have a variety of references
>> to
>> > either main application classes or standard library classes in the main
>> > application.  The main application dependencies are resolved by Buildr
>> by
>> > using a toolkit of Ruby code (libraries it uses for construction of the
>> > configurations) and jar files that is deployed as a Maven repo.  If they
>> > also contain Java code tehmselves, they need to have the references to
>> that
>> > code in their configuration files.  The main application has its own
>> > dependency injection mechanism that looks at these configuration files
>> and
>> > uses its classloader to load these classes.  To make it more
>> interesting, I
>> > also have written a buildr code generator to build the build system.
>>  (Sort
>> > of like a Rails generator.)
>> >
>> > Despite the inherent complexity, this works end to end fine.  The only
>> real
>> > issue is *not* in building or deploying, it is in the built in tests
>> that
>> > the build system manufactures.  By default two basic kinds of tests are
>> > run:
>> > first, the presence of every required configuration file is checked
>> inside
>> > the product jars with rspec; second, every class referenced in the
>> > configuration files is checked using Java.java.lang.Class.forName().
>> >
>> > 2.  The problem is the second test, Class.forName(), it can no longer
>> see
>> > the classes the build system creates.  This is a GREAT feature, and I
>> put a
>> > lot of effort into it, so it would be nice to make it work.  However, I
>> can
>> > function by "turning it off". :((
>> >
>> > Here's a simple example:
>> >
>> > To avoid the readonly nature of the CLASSPATH, very early on I set the
>> > CLASSPATH to INCLUDE the target jars that do no yet exist.  And this
>> used
>> > to
>> > work like a champ....
>> >      FileList[LIBS].each do |lib|
>> >         Java.classpath << lib
>> >      end
>> >      # package products: explicit, they DO NOT EXIST YET
>> >      Java.classpath << "#{RELEASE}/ext-lib/common.jar"
>> >      Java.classpath << "#{RELEASE}/lib/#{GROUP}-#{VERSION_NUMBER}.jar"
>> >      Java.classpath <<
>> > "#{RELEASE}/lib/#{GROUP}-#{vertical}-#{VERSION_NUMBER}.jar"
>> >
>> > RELEASE is just a directory that reassembles the jar products with
>> possibly
>> > designated other jars.  This is a build option.
>> >
>> > I then do tests that come down to the equivalent of
>> >
>> >
>> >
>> Java.java.lang.Class.forName("com.mypackage.SomeImpl").asSubclass(Java.java.lang.Class.forName("com.mypackage.SomeIfc")
>> >
>> > That's the problem in a nutshell!
>> >
>> > Pretty obvious if I specify a type of component, it must both exist, and
>> be
>> > the correct type for the component.  It also means that I will know that
>> > there is a typo in the configuration I will catch it before I deploy my
>> > jars
>> > in the main application.  Unfortunately, now I cannot do that.
>> >
>> > So to test it, all you need to do it have buildr build you a project,
>> add
>> > one class to the source directory, add in the target package jar to the
>> > classpath in a location that it will eventually be in.  Then make a task
>> > that depends on packaging (or packaging and copying to the location you
>> > designate) and that runs the Class.forName check.  My prediction is
>> that,
>> > if
>> > properly constructed, this will work on Linux, on Windows, and on a Mac
>> > with
>> > an earlier JVM, but NOT with the latest Mac JVM (with the header files
>> > restored).
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> > On Mon, Nov 29, 2010 at 6:45 PM, Alex Boisvert <[email protected]
>> > >wrote:
>> >
>> > > Can you post a simple example of what you're trying to do?
>> > >
>> > > On Monday, November 29, 2010, Ed Smiley <[email protected]> wrote:
>> > > > Couldn't get that to work....
>> > > >
>> > > > On Wed, Nov 17, 2010 at 3:54 PM, Ed Smiley <[email protected]>
>> wrote:
>> > > >
>> > > >> Interesting.
>> > > >>
>> > > >> I saw a post by "Arton", the guy mentioned in the release notes,
>> > > indicating
>> > > >> that the proper way to add a jar to the classpath is using the new
>> > > dynamic
>> > > >> functionality
>> > > >>
>> > > >> Rjb::add_classpath, rather than setting it really early on though
>> > > >> Java.classpath.  I am messing with that approach, currently.
>> > > >>
>> > > >> On Wed, Nov 17, 2010 at 9:50 AM, Alex Boisvert <
>> > [email protected]
>> > > >wrote:
>> > > >>
>> > > >>> There were some changes in RJB between 1.2.5 and 1.3.3 related to
>> > > >>> classloading.  In particular, RJB now uses a URLClassLoader
>> instead
>> > of
>> > > the
>> > > >>> JVM's system classloader.
>> > > >>>
>> > > >>> https://github.com/arton/rjb/blob/master/ChangeLog
>> > > >>>
>> > > >>> <https://github.com/arton/rjb/blob/master/ChangeLog>Not sure it
>> > causes
>> > > >>> the
>> > > >>> issue you're seeing but I thought it worth mentioning.
>> > > >>>
>> > > >>> alex
>> > > >>>
>> > > >>>
>> > > >>> On Wed, Nov 17, 2010 at 8:59 AM, Ed Smiley <[email protected]>
>> > wrote:
>> > > >>>
>> > > >>> > In the aftermath of changing over to getting Buildr to work with
>> > the
>> > > new
>> > > >>> > JVM, I am seeing yet another issue, this one a tad obscure.
>> > > >>> > It's a little complicated to explain so bear with me.
>> > > >>> >
>> > > >>> > In code (that is essentially the same and was working before) I
>> had
>> > a
>> > > >>> step
>> > > >>> > where I set up a Java classpath early on in the build process
>> which
>> > > >>> > included
>> > > >>> > my (not yet existing) package jar file products.  I calculate
>> where
>> > > they
>> > > >>> > would end up and what they would be called to avoid a circular
>> > > >>> dependency
>> > > >>> > on
>> > > >>> > package object, and also to set the classpath for RJB early on
>> (as
>> > it
>> > > >>> lets
>> > > >>> > you set it later, but does not honor the new value).  I then
>> have a
>> > > >>> > validation step where a list of Java classes and their expected
>> > > >>> subclasses
>> > > >>> > are instantiated (using
>> > > >>> >
>> > > >>> >
>> > > >>>
>> > >
>> >
>> Java.java.lang.Class.forName(dep.class).asSubclass(Java.java.lang.Class.forName(dep.subclass))).
>> > > >>> >  As odd as it sounds this worked correctly, and have been using
>> > this
>> > > for
>> > > >>> > the
>> > > >>> > last six weeks until I hit this snag.
>> > > >>> >
>> > > >>> > Now (and I put in debugging to ensure that that classpath is as
>> I
>> > > think
>> > > >>> it
>> > > >>> > is and that the jar file exists before running this check)
>> classes
>> > > that
>> > > >>> are
>> > > >>> > built in my jars are unable to be instantiated by the RJB Java
>> > object
>> > > >>> and I
>> > > >>> > get spurious errors.
>> > > >>> >
>> > > >>> > Any insights?  Has this environment done something to unhinge
>> the
>> > RJB
>> > > >>> > "classpath lifecycle"?  Perhaps something now creating the JVM
>> > > earlier?
>> > > >>> >
>> > > >>>
>> > > >>
>> > > >>
>> > > >
>> > >
>> >
>>
>
>

Reply via email to