buildr-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Boisvert <alex.boisv...@gmail.com>
Subject Re: Java
Date Tue, 30 Nov 2010 21:24:39 GMT
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 <esmiley@ebrary.com> 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 <alex.boisvert@gmail.com
> >wrote:
>
> > Can you post a simple example of what you're trying to do?
> >
> > On Monday, November 29, 2010, Ed Smiley <esmiley@ebrary.com> wrote:
> > > Couldn't get that to work....
> > >
> > > On Wed, Nov 17, 2010 at 3:54 PM, Ed Smiley <esmiley@ebrary.com> 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 <
> alex.boisvert@gmail.com
> > >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 <esmiley@ebrary.com>
> 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?
> > >>> >
> > >>>
> > >>
> > >>
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message