struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From micael <caraun...@harbornet.com>
Subject Re: [OT - Java] How can I do this in Java?
Date Mon, 30 Sep 2002 21:24:45 GMT
I could not agree more on reflection.  The management potential of 
reflection is huge.  I really like Stuart Dabbs Halloway's book "Component 
Development for the Java Platform," which is really reflection based in 
essence, and love the JMX API.  Still, the present problem is not a very 
good example of the proper use of reflection.  Just tossing my three cents 
in.  I wish I had a job where I could work on the development of Java 
management tools with JMX.  Man!  That would be a kick!  The possibilities 
are staggering.

At 12:22 PM 9/30/2002 -0700, you wrote:
>Comments intermixed.
>
>On Mon, 30 Sep 2002, John Bindel wrote:
>
> > Date: Mon, 30 Sep 2002 13:49:22 -0500
> > From: John Bindel <jbindel@works.com>
> > Reply-To: Struts Users Mailing List <struts-user@jakarta.apache.org>
> > To: Struts Users Mailing List <struts-user@jakarta.apache.org>
> > Subject: Re: [OT - Java] How can I do this in Java?
> >
> > On Mon, Sep 30, 2002 at 12:02:41PM -0500, Jerry Jalenak wrote:
> >
> > > Yeah, already ran across the exceptions. Right now I'm trying
> > > to decide how to handle them since all of this code is actually
> > > in a custom Validator routine.....
> >
> > Good Lord, people, why is reflection anything but the option of
> > last resort here?
> >
>
>While I agree with you that using reflection was a poor design choice for
>the problem stated here (the patterns should really be loaded from a data
>file instead of introspecting from the class), your condemnation of
>reflection in general is based on an incorrect definition of the term, and
>also outdated behavior related to performance.  See below for more.
>
> > You really do not want to be calling Class.forname(String) unless
> > there is some class that cannot be loaded by the compiler. First,
> > calling Class.forname is slow, and second, it perversely gets
> > rid of the compile-time type-safety that you would have is you
> > simply used MyClass.class.
> >
>
>The Class.forName() method is not really reflection -- it is dynamic class
>loading.  Struts itself uses this to good effect, because it's not
>possible to know (at the time ActionServlet is compiled) the names of all
>the Action and ActionForm subclasses that *your* application will be
>using.
>
>Further, there is no loss of type safety when using dynamic class loading
>in the usual fashion, because you normally cast to the base class you are
>looking for.  For example, module error checking, this is how Struts
>actually loads an Action class instance:
>
>   ClassLoader loader =
>     Thread.currentThread().getContextClassLoader();
>   if (classLoader == null) {
>     loader = this.getClass().getClassLoader();
>   }
>   Action action = (Action) loader.loadClass(actionClassName);
>
>Note the cast to an Action, which protects you from type safety problems.
>
>Of course, using dynamic class loading in the use case being discussed in
>this mail thread was totally unnecesary.  But please stop casting
>aspersions on a very useful feature of the Java language that makes
>dynamically extensible applications like Struts possible in the first
>place.
>
> > Reflection is a tool that's useful when you do not know at build
> > time the classes with which you will be dealing. It's useful for
> > discovery of APIs. Using reflection instead of a lookup table
> > is needlessly obtuse and will cause your VM to do all sorts of
> > work on which any programmer should not want to be wasting CPU
> > cycles.
> >
> >
> > 1. Using reflection here is fragile, especially if it's not wrapped
> > within the class that defines your constants. Java is a strongly
> > typed language so letting the compiler help you is encouraged.
> >
>
>Since the problem at hand was to access *data*, the best approach would be
>to store the patterns externally in a properties file.  Then, the data
>could be used by multiple classes when it is needed (including the class
>in which the format strings are currently embedded).
>
> > 2. Using reflection is slow. If you still think it's the way you
> > want to go, I would strongly recommend limiting the times you
> > call Class.forname, etc., such that you do not call it every time
> > you validate the zip code.
> >
>
>Firstly, as above, Class.forName() is not reflection.
>
>Secondly, a subsequent call to Class.forName() for the same class name is
>*not* going to load the class bytecodes again; the class loader will
>remember that the requested class name has already been loaded, and just
>returns you the same instance.
>
>Thirdly, there is *zero* performance difference (at runtime) between
>loading a class via Class.forName() and loading one (for the first time)
>with a "new" operator.  Why?  Because they both end up calling the exact
>same loadClass() method -- it's just a question of whether the developer
>calls the method explicitly or the bytecodes generated by the compiler
>call it for you.
>
>As for the performance of real life uses of reflection, have you ever
>noticed how Struts actually implements the population of your form bean
>properties from the request parameters?  Yep ... that's right ... every
>single call to a property setter is done via reflection.  Seems fast
>enough to me, especially on a 1.4 JDK where the performance difference
>between direct calls and reflected calls is very very small.
>
> > 3. Using reflection makes you check all sorts of exceptions for
> > things that you as the programmer know should not occur, but only
> > can be you are circumventing the type checking provided by the
> > language.  This is a clue that what should be a simple task is
> > being made more complex than it needs to be.
> >
>
>In the particular use case at hand, reflection is the wrong technology to
>use.  However, it makes possible some things that would otherwise be
>impossible, or insanely complicated (to do form bean population without
>using reflection, Struts would have to examine all your form beans, then
>generate a custom Java class to do the auto-population and make sure these
>classes were all compiled and included in your webapp -- not something
>that can be guaranteed in a portable fashion).
>
> > 4. I'm not sure what your application is, but using regexp strings
> > to validate ZIP codes per state seems like a bad idea. The US
> > post office makes new ZIP codes all the time, and unless you are
> > getting a list from them every week, the most you may want your
> > application to do is warn the user that the application doesn't
> > recognize the ZIP code.
> >
>
>It doesn't look like he wanted to check the exact codes, just that the
>code is in the correct range for that state.  This is a perfectly
>reasonable compromise if you cannot afford the time to do the database
>lookup, or you don't have the mechanisms to maintain a current list of all
>the individual codes in your database.
>
> > 5. Tell your product managers that validating ZIP codes is not
> > something you can do reliably without an often-updated list of
> > ZIP codes that you would need to download from the Post Office
> > on a regular schedule since your list of regexp string will
> > become outdated.
> >
> > 6. Lookup tables implemented by arrays or HashMaps are orders
> > of magnitude faster than the sequence of function calls and system
> > calls that you have to do with reflection.
> >
> >
> > I'm sorry I had to write this, but I am befuddled by the lack
> > of outcry over using reflection instead of a simple lookup table.
> >
>
>I'm saddened by the fact that you take a case of misuese of a particular
>feature and turn it into a diatribe against ever using it.
>
> > Cheers,
> > John
>
>Craig
>
>
> >
> > > > -----Original Message-----
> > > > From: Taylor, Jason [mailto:jtaylor@cobaltgroup.com]
> > > > Sent: Monday, September 30, 2002 11:57 AM
> > > > To: 'Struts Users Mailing List'
> > > > Subject: RE: [OT - Java] How can I do this in Java?
> > > >
> > > >
> > > > good point-- you'd also want to printStackTrace() (if possible) before
> > > > rethrowing InvocationTargetException, since it can be
> > > > difficult to debug an
> > > > ITE otherwise...
> > > >
> > > > -----Original Message-----
> > > > From: Daniel Jaffa [mailto:jaffad@courtinnovation.org]
> > > > Sent: Monday, September 30, 2002 9:49 AM
> > > > To: Struts Users Mailing List
> > > > Subject: Re: [OT - Java] How can I do this in Java?
> > > >
> > > >
> > > > Make sure your code in a  proper try and catch.  Using
> > > > reflection spits out
> > > > nasty errors if  anything is not right.:(
> > > >
> > > > ClassCastException
> > > > IllegalAccessException
> > > > NoSuchMethodException
> > > > InvocationTargetException
> > > >
> > > > Daniel jaffa
> > > > ----- Original Message -----
> > > > From: "Jerry Jalenak" <Jerry.Jalenak@LABONE.com>
> > > > To: "'Struts Users Mailing List'" <struts-user@jakarta.apache.org>
> > > > Sent: Monday, September 30, 2002 11:46 AM
> > > > Subject: RE: [OT - Java] How can I do this in Java?
> > > >
> > > >
> > > > > Jason - Thanks for the code snippet - worked like a charm
> > > > first time!  I
> > > > > tend to get lost in JavaDoc sometimes, so this was a nice
> > > > example to have
> > > > on
> > > > > how to wind my way through to the answer!  Thanks again!
> > > > >
> > > > > John - Thanks for the suggestion on using the HashMap.  I'm
> > > > going to file
> > > > it
> > > > > away for now and use Jason's reflection method - but it
> > > > never hurts to
> > > > have
> > > > > a couple of different methods to use on something like this!
> > > > >
> > > > > Thanks guys!
> > > > >
> > > > > Jerry
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Taylor, Jason [mailto:jtaylor@cobaltgroup.com]
> > > > > > Sent: Monday, September 30, 2002 10:28 AM
> > > > > > To: 'Struts Users Mailing List'
> > > > > > Subject: RE: [OT - Java] How can I do this in Java?
> > > > > >
> > > > > >
> > > > > > I don't happen to have any sample code that does exactly what
> > > > > > you're doing,
> > > > > > but off the top of my head (with a little help from sun's
> > > > > > javadoc) I'd say
> > > > > > it's something like:
> > > > > >
> > > > > > import java.lang.reflect.Field;
> > > > > >
> > > > > > String stateCode = "AK";
> > > > > > Class constantClass =
> > > > > > Class.forName("com.yourdomain.yourapp.Constants");
> > > > > > Field stateField = constantClass.getDeclaredField(stateCode);
> > > > > > String stateRegExp = (String) stateField.get(constantClass);
> > > > > > System.err.println("regexp for "+stateCode+": "+stateRegExp);
> > > > > >
> > > > > > I don't really know any more about reflection than you, I
> > > > > > just followed the
> > > > > > trail from java.lang.Class to java.lang.reflect.Field.  Once
> > > > > > you've done it
> > > > > > once, you see it's no mystery-- you're just doing runtime
> > > > compiling.
> > > > > >
> > > > > > HTH-- This is just how I'd start, as I haven't tested or used
> > > > > > this code.  If
> > > > > > I'm wrong, I'm sure you can figure out what I missed by
> > > > > > studying the API
> > > > > > docs.  If, on the other hand, you don't like reading javadocs
> > > > > > and generating
> > > > > > your own test cases, LOL!
> > > > > >
> > > > > > -JT
> > > > > >
> > > > > > -----Original Message-----
> > > > > > From: Jerry Jalenak [mailto:Jerry.Jalenak@LABONE.com]
> > > > > > Sent: Monday, September 30, 2002 8:05 AM
> > > > > > To: 'Struts Users Mailing List'
> > > > > > Subject: RE: [OT - Java] How can I do this in Java?
> > > > > >
> > > > > >
> > > > > > Jason,
> > > > > >
> > > > > > Thanks for the quick reply.  I just took at look at the
> > > > > > API's, but don't yet
> > > > > > understand enough about reflection to know how to
> > > > implement it.  Just
> > > > > > looking at the methods I don't see a way to do what I want -
> > > > > > any chance that
> > > > > > you'd have some sample code laying about?
> > > > > >
> > > > > > Jerry
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Taylor, Jason [mailto:jtaylor@cobaltgroup.com]
> > > > > > > Sent: Monday, September 30, 2002 9:59 AM
> > > > > > > To: 'Struts Users Mailing List'
> > > > > > > Subject: RE: [OT - Java] How can I do this in Java?
> > > > > > >
> > > > > > >
> > > > > > > sounds like a job for reflection (java.lang.reflect.*;)
Have
> > > > > > > you looked at
> > > > > > > java.lang.Class and java.lang.reflect.Field?
> > > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Jerry Jalenak [mailto:Jerry.Jalenak@LABONE.com]
> > > > > > > Sent: Monday, September 30, 2002 7:50 AM
> > > > > > > To: 'struts-user@jakarta.apache.org'
> > > > > > > Subject: [OT - Java] How can I do this in Java?
> > > > > > >
> > > > > > >
> > > > > > > OK - off topic, but Sun's java forum sucks, and there are
an
> > > > > > > incredible
> > > > > > > number of Java guru's on this list, so I thought I'd throw
> > > > > > > this out here.
> > > > > > > (That and I am using this in a custom validation routine
> > > > > > > :-))    Any help
> > > > > > > would be GREATLY appreciated!
> > > > > > >
> > > > > > > Here's the scenario - I've got a series of static constants
> > > > > > > that represent
> > > > > > > Java regular expressions.  These RE's are used to validate
> > > > > > > driver license
> > > > > > > formats for the 50 states + DC.  The strings look like
this:
> > > > > > >
> > > > > > > public static final String AK = "^[0-9]{1,7}$";
> > > > > > > public static final String AL = "^[0-9]{7}$";
> > > > > > > public static final String AR = "^[0-9]{8,9}$";
> > > > > > > public static final String AZ =
> > > > > > > "^[0-9ABDY][0-9]{8}$|^[A-Z][0-9]{3,6}$|^[A-Z]{2}[0-9]{3,5}$";
> > > > > > > public static final String CA = "^[A-Z][0-9]{4,7}$";
> > > > > > > public static final String CO =
> > > > > > > "^[A-Z][0-9]{1,6}$|^[A-Z]{2}[0-9]{1,6}$|^[0-9]{9}$";
> > > > > > > etc. etc. etc.
> > > > > > >
> > > > > > > On my form I have a drop-down box of states, and a field
for
> > > > > > > the license
> > > > > > > number.  In my custom validator routine, I pick up the
value
> > > > > > > of the state,
> > > > > > > and build a string to represent the constant - i.e.
> > > > > > >
> > > > > > > private static boolean validateDriversLicenseNumber(String
> > > > > > > licenseState, String licenseNumber)
> > > > > > > {
> > > > > > > String licenseConstant = "Constants." + licenseState;
> > > > > > >
> > > > > > > I then want to use "licenseConstant" in a Pattern / Match:
> > > > > > >
> > > > > > > Pattern p = Pattern.compile(licenseConstant,
> > > > > > > Pattern.CASE_INSENSITIVE);
> > > > > > > Match m = p.matcher(licenseNumber);
> > > > > > > return (m.find());
> > > > > > > }
> > > > > > >
> > > > > > > Obviously the line "String licenseConstant = "Constants."
+
> > > > > > > licenseState;"
> > > > > > > does not give me the value of Constant.<state name>;
the
> > > > > > > question I have is,
> > > > > > > is there a method (or something) that will allow me to
build
> > > > > > > such a string,
> > > > > > > and return the value (i.e. the regular expression)?  Or
is
> > > > > > > there a better
> > > > > > > way of doing this?
> > > > > > >
> > > > > > > TIA!
> > > > > > >
> > > > > > > Jerry Jalenak
> > > > > > > Web Publishing
> > > > > > > LabOne, Inc.
> > > > > > > 10101 Renner Blvd.
> > > > > > > Lenexa, KS  66219
> > > > > > > (913) 577-1496
> > > > > > > jerry.jalenak@labone.com
> > > > > > >
> > > > > > >
> > > > > > > This transmission (and any information attached to it)
may be
> > > > > > > confidential
> > > > > > > and is intended solely for the use of the individual or
> > > > > > > entity to which it
> > > > > > > is addressed. If you are not the intended recipient or
> > > > the person
> > > > > > > responsible for delivering the transmission to the intended
> > > > > > > recipient, be
> > > > > > > advised that you have received this transmission in error
and
> > > > > > > that any use,
> > > > > > > dissemination, forwarding, printing, or copying of this
> > > > > > information is
> > > > > > > strictly prohibited. If you have received this transmission
> > > > > > > in error, please
> > > > > > > immediately notify LabOne at (800)388-4675.
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > --
> > > > > > > To unsubscribe, e-mail:
> > > > > > > <mailto:struts-user-unsubscribe@jakarta.apache.org>
> > > > > > > For additional commands, e-mail:
> > > > > > > <mailto:struts-user-help@jakarta.apache.org>
> > > > > > >
> > > > > >
> > > > > > This transmission (and any information attached to it) may be
> > > > > > confidential
> > > > > > and is intended solely for the use of the individual or
> > > > > > entity to which it
> > > > > > is addressed. If you are not the intended recipient or the person
> > > > > > responsible for delivering the transmission to the intended
> > > > > > recipient, be
> > > > > > advised that you have received this transmission in error and
> > > > > > that any use,
> > > > > > dissemination, forwarding, printing, or copying of this
> > > > information is
> > > > > > strictly prohibited. If you have received this transmission
> > > > > > in error, please
> > > > > > immediately notify LabOne at (800)388-4675.
> > > > > >
> > > > > >
> > > > > >
> > > > > > --
> > > > > > To unsubscribe, e-mail:
> > > > > > <mailto:struts-user-unsubscribe@jakarta.apache.org>
> > > > > > For additional commands, e-mail:
> > > > > > <mailto:struts-user-help@jakarta.apache.org>
> > > > > >
> > > > >
> > > > > This transmission (and any information attached to it) may
> > > > be confidential
> > > > and is intended solely for the use of the individual or
> > > > entity to which it
> > > > is addressed. If you are not the intended recipient or the person
> > > > responsible for delivering the transmission to the intended
> > > > recipient, be
> > > > advised that you have received this transmission in error and
> > > > that any use,
> > > > dissemination, forwarding, printing, or copying of this information is
> > > > strictly prohibited. If you have received this transmission
> > > > in error, please
> > > > immediately notify LabOne at (800)388-4675.
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > To unsubscribe, e-mail:
> > > > <mailto:struts-user-unsubscribe@jakarta.apache.org>
> > > > > For additional commands, e-mail:
> > > > <mailto:struts-user-help@jakarta.apache.org>
> > > > >
> > > >
> > > >
> > > > --
> > > > To unsubscribe, e-mail:
> > > > <mailto:struts-user-unsubscribe@jakarta.apache.org>
> > > > For additional commands, e-mail:
> > > > <mailto:struts-user-help@jakarta.apache.org>
> > > >
> > >
> > > This transmission (and any information attached to it) may be 
> confidential and is intended solely for the use of the individual or 
> entity to which it is addressed. If you are not the intended recipient or 
> the person responsible for delivering the transmission to the intended 
> recipient, be advised that you have received this transmission in error 
> and that any use, dissemination, forwarding, printing, or copying of this 
> information is strictly prohibited. If you have received this 
> transmission in error, please immediately notify LabOne at (800)388-4675.
> > >
> > >
> > >
> > > --
> > > To unsubscribe, 
> e-mail:   <mailto:struts-user-unsubscribe@jakarta.apache.org>
> > > For additional commands, e-mail: 
> <mailto:struts-user-help@jakarta.apache.org>
> >
> > --
> > end of line
> >
> >
> > --
> > To unsubscribe, 
> e-mail:   <mailto:struts-user-unsubscribe@jakarta.apache.org>
> > For additional commands, e-mail: 
> <mailto:struts-user-help@jakarta.apache.org>
> >
> >
>
>
>--
>To unsubscribe, e-mail:   <mailto:struts-user-unsubscribe@jakarta.apache.org>
>For additional commands, e-mail: <mailto:struts-user-help@jakarta.apache.org>



--
To unsubscribe, e-mail:   <mailto:struts-user-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:struts-user-help@jakarta.apache.org>


Mime
View raw message