Re: This is just plain ... odd.

2012-11-09 Thread Lyallex
  I have a facade that publishes a method that contracts to return a
  list of categories ordered alphabetically

 All problems in computer science can be solved by another layer of
 abstraction. Sure you can't fit a Proxy to a Service in there?


Hmm an oldie but goodie we can discuss software analysis and design if you
like
but it's a bit OT.


 [snip]



 What does that custom tag do? A beer says it sorts something. Or,
 maybe you have some silly client-side process that sorts the entries
 after they are loaded into the browser.


Well I quite like Wadworth 6X I'll give you my paypal account address and
you can deposit £3.30 :-))
I can assure you I'm quite familiar with my own code and no secondary sort
is going on.

As succinctly as possible

MySQL returns results sorted by primary key by default AFAIAA
no explicit sorting is done in the database access code

/* Category server (database access) */
public ListCategory getCategories(Connection conn) throws
CategoryServerException{
String sql = select * from Category;

populate list then return it NO SORTING

/* facade deals with transactional connections etc*/
public ListCategory getAllCategories() throws CategoryException
CategoryServer categories = new CategoryServer();
allcats = categories.getCategories(conn);
Collections.sort(allcats);

/* Initialization servlet */
CategoryFacade cats = new CategoryFacade();
ListCategory categories = cats.getAllCategories();
getServletContext().setAttribute(WebConstants.ALPHACATS, categories);

/* CategoryWriter custom tag */
ListCategory cats =(ListCategory)
pageContext.getServletContext().getAttribute(WebConstants.ALPHACATS);
IteratorCategory iter = cats.iterator();
Category c = null;
StringBuffer buf = new StringBuffer();
 while(iter.hasNext()){
   //build the output
//output it

That's it, really, there is no more

I need to get to the bottom of this as it's bugging the hell out of me
a pound to a penny says it's something simple/stupid. I'll try what you
suggest re wrapping the collection

Thanks

Lyallex


Re: This is just plain ... odd.

2012-11-09 Thread Lyallex
Don't shout at me for top posting
In this instance it's justified

Thanks for your continued work on this. I have to get some lines of code
down
as release date is fast approaching but I will try your code as soon as I
have time

Thanks for you continued work on this

Lyallex

On 9 November 2012 05:08, Christopher Schultz
ch...@christopherschultz.netwrote:

 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

 Russ,

 On 11/8/12 6:05 PM, Russ Kepler wrote:
  On Thursday, November 08, 2012 07:36:20 PM Lyallex wrote:
 
  The only difference between the two executions is the fact that
  the test code executes in it's own instance of the JVM whereas
  the other execution runs in an instance shared with the
  container.
 
  I accept that the behaviour may be undefined even though it is
  consistently repeatable in both environments but surely given
  everything else being equal the results should be the same ... or
  maybe I'm just losing the plot.
 
  No, you're right but just missing some small difference in the
  environments.
 
  I'd verify that you get the same input data in the same order in
  both cases, and that you're starting with the same size container
  [...]

 After writing a bench test that I couldn't get to fail, your comment
 here tripped a thought in my brain: the container size. So, I added
 an element to my list of Strings and boom: failure. It turns out that
 the collection size doesn't matter: I just hadn't been iterating
 enough, so I added a loop that will run until the initial sorted order
 doesn't match the re-sorted order (with shuffles in between).

 Lyallex, see the code below: it will fail after a few iterations to
 produce the same element ordering. Switch from BrokenSorter to
 WorkingSorter and you'll find that it runs forever.

 Are you *sure* that your database always returns the items in the same
 order? If you plan on sorting alphabetically later, why bother sorting
 by id when fetching? Unless you are really sorting by id when
 fetching, the data can come back in any order. It may *often* be in
 entry-sequenced order, but it is certainly not guaranteed to be.

 The code below shows that, without any funny business, the sort can
 work sometimes and not in others.

 Enjoy,
 - -chris

 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;

 public class SortTest
 {
 public static void main(String[] args)
 {
 String[] fruits = new String[] {
 Apples,
 Bananas,
 Coconuts,
 Dates,
 Eggplants,
 Figs,
 Grapefruits,
 Honeydews,
 Ilamas,
 Jambolans,
 Kepels,
 Lemons,
 Miscellaneous,
 Nectarines
 };

 ListString fruitList = Arrays.asList(fruits);

 ComparatorString sorter = new BrokenSorter();

 System.out.println(Initial order:  + fruitList);

 Collections.sort(fruitList, sorter);
 System.out.println(Sort 1:  + fruitList);

 ListString saved = new ArrayListString(fruitList);

 int i = 1;
 do
 {
 Collections.shuffle(fruitList);
 Collections.sort(fruitList, sorter);
 System.out.println(Sort  + (++i) + :  + fruitList);
 }
 while(fruitList.equals(saved));
 System.out.println(Stopped after  + i +  iterations because
 the list did not sort the same way.);
 }

 static class BrokenSorter
   implements ComparatorString
 {
 @Override
 public int compare(String a, String b)
 {
   if(a.equals(Miscellaneous))
   return 1;
   return a.compareTo(b);
 }
 }
 static class WorkingSorter
   implements ComparatorString
 {
 @Override
 public int compare(String a, String b)
 {
   if(a.equals(Miscellaneous))
   return 1;

   if(b.equals(Miscellaneous))
   return -1;

   return a.compareTo(b);
 }
 }
 }
 -BEGIN PGP SIGNATURE-
 Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
 Comment: GPGTools - http://gpgtools.org
 Comment: Using GnuPG with Mozilla - http://www.enigmail.net/

 iEYEARECAAYFAlCcj7cACgkQ9CaO5/Lv0PBpawCeORBT62XWcjyw+SruT6Bhkh50
 sDEAn1ZjSiPR70+DV/QVBFOjXKjH498o
 =F3QS
 -END PGP SIGNATURE-

 -
 To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
 For additional commands, e-mail: users-h...@tomcat.apache.org




This is just plain ... odd.

2012-11-08 Thread Lyallex
Java 1.6
Tomcat 6.0.35
Ubuntu Linux 12.04

I thought about posting this to a Java list but I can't
reproduce it 'standalone' so I thought I'd have a go here.

It's quite long and involved...

I have a web application that lists items for sale by category

I have a facade that publishes a method that contracts to return
a list of categories ordered alphabetically
The category 'Miscellaneous' is required to be appended to the end of the
list.

My facade calls out to a database server that returns a ListCategory
in random order. I then call collections.sort on the list and return the
result.

I've been messing around with various things and I have come up against a
very
strange problem.

One way of satisfying the contract is to write the Category class as follows
I'm not suggesting this is in any way acceptable industrial strength
code, I'm doing it to illustrate a point.

public class Category implements ComparableCategory{

private Integer categoryId = 0;
private String category = ;

   @Override
   public int compareTo(Category c) {
  if(category.equals(Miscellaneous)){
  return 1;
   }
   else{
  return category.compareTo(c.category);
   }
}

etc

If I test this by running a client of the facade
I get the expected results, the list is ordered as required with
Miscellaneous on the end

However, and here's the thing, When my app starts
an initialisation servlet runs, calls the facade method
and puts the resulting List on the application context.
When I render the list via a custom tag the list has
in some way been altered so that the String
Miscellaneous is in it's 'natural' position
not what I want at all.

I have tried everything I can think of to reproduce this behaviour
in a standalone Java program but the list is always returned
as required. When I call the method from a servlet the list is always
returned
in it's natural order, I know collections.sort is being executed as
the list is in alpha order, it's almost as if the comparator is being
replaced in some way

I have no servlet filters or any other code 'in the way' between the facade
and the initialization servlet.

Any ideas ?

TIA

Lyallex


Re: This is just plain ... odd.

2012-11-08 Thread Russ Kepler
On Thursday, November 08, 2012 01:35:55 PM Lyallex wrote:

 I have tried everything I can think of to reproduce this behaviour
 in a standalone Java program but the list is always returned
 as required. When I call the method from a servlet the list is always
 returned
 in it's natural order, I know collections.sort is being executed as
 the list is in alpha order, it's almost as if the comparator is being
 replaced in some way
 
 I have no servlet filters or any other code 'in the way' between the facade
 and the initialization servlet.
 
 Any ideas ?

I'm not sure that you can ever get consistent results if the input order is 
random.  The Collections.sort() implements a merge sort and the merge sort 
depends on a consistent result from the compare() method.  As implemented the 
compare() will return what you want when the object being compared against is 
the Misc object but return a string compare when it isn't.  Try this:

   @Override
   public int compareTo(Category c) {
  if(category.equals(Miscellaneous)){
  return 1;
   } elseif (c.category.equals(Miscellaneous)) {
return -1;
   else{
  return category.compareTo(c.category);
   }
}

(side comment: If the list is a decent size it might make sense to compare 
against the Misc object rather than compare all strings but it's likely not 
worth the bother).

The was I usually handle this is to .remove the offending object from the list, 
sort, then .add it back on after the sort.  Keep the odd code local to the 
oddity.

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: This is just plain ... odd.

2012-11-08 Thread DJohnson
Russ Kepler r...@kepler-eng.com wrote on 11/08/2012 09:22:41 AM:

 From: Russ Kepler r...@kepler-eng.com
 To: Tomcat Users List users@tomcat.apache.org, 
 Date: 11/08/2012 09:23 AM
 Subject: Re: This is just plain ... odd.
 
 On Thursday, November 08, 2012 01:35:55 PM Lyallex wrote:

  I have tried everything I can think of to reproduce this behaviour
  in a standalone Java program but the list is always returned
  as required. When I call the method from a servlet the list is always
  returned
  in it's natural order, I know collections.sort is being executed as
  the list is in alpha order, it's almost as if the comparator is being
  replaced in some way
 
  I have no servlet filters or any other code 'in the way' between the 
facade
  and the initialization servlet.
 
  Any ideas ?

 I'm not sure that you can ever get consistent results if the input order 
is
 random.  The Collections.sort() implements a merge sort and the merge 
sort
 depends on a consistent result from the compare() method.  As 
implemented the
 compare() will return what you want when the object being compared 
against is
 the Misc object but return a string compare when it isn't.  Try this:

 @Override
 public int compareTo(Category c) {
 if(category.equals(Miscellaneous)){
 return 1;
 } elseif (c.category.equals(Miscellaneous)) {
 return -1;
 else{
 return category.compareTo(c.category);
 }
 }

 (side comment: If the list is a decent size it might make sense to 
compare
 against the Misc object rather than compare all strings but it's likely 
not
 worth the bother).

 The was I usually handle this is to .remove the offending object 
 from the list,
 sort, then .add it back on after the sort.  Keep the odd code local to 
the
 oddity.

This is closer, but still doesn't work correctly if two Misc categories 
are being compared, or one Misc category is compared to itself. 
Try: 

@Override
public int compareTo(Category c) {
if(category.equals(Miscellaneous)) {
if(category.equals(c.category) return 0; // correctly 
handle equality. 
else return 1;
} elseif (c.category.equals(Miscellaneous)) {
return -1;
} else {
return category.compareTo(c.category);
}
}

---
David S. Johnson
DeskNet Inc.





Re: This is just plain ... odd.

2012-11-08 Thread Lyallex
 I'm not sure that you can ever get consistent results if the input order is
 random.


Well perhaps 'random' was a bit 'random' the select returns the data in the
same order it was entered, ordered by id.
Not necessarily the same as alpha as I'm sure you appreciate. the fact is
that the data was always returned in the same order
by the database, just not the order I wanted. This is why I was
particularly confused.

Whatever, your code works, now I just gotta figure out why

Thanks

Lyallex


Re: This is just plain ... odd.

2012-11-08 Thread Russ Kepler
On Thursday, November 08, 2012 03:06:51 PM Lyallex wrote:
  I'm not sure that you can ever get consistent results if the input order
  is
  random.
 
 Well perhaps 'random' was a bit 'random' the select returns the data in the
 same order it was entered, ordered by id.
 Not necessarily the same as alpha as I'm sure you appreciate. the fact is
 that the data was always returned in the same order
 by the database, just not the order I wanted. This is why I was
 particularly confused.
 
 Whatever, your code works, now I just gotta figure out why

Because you were only handling one end of the compare against the special 
object.  Since the special object could appear as the object to be compared 
against as well as the object performing the compare the merge sort was being 
given conflicting comparisons against the special object - always the greatest 
when the special was performing the compare and alphabetically(ish) when it 
was the object given to the compare method.

You got the same (wrongish) results since you gave the sort the same order in 
the list.  I can't recall how merge sort can freak out when given conflicting 
compares, I seem to recall that you might get an endless loop under some 
circumstances as it orders and reorders the same group of objects.

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: This is just plain ... odd.

2012-11-08 Thread Russ Kepler
On Thursday, November 08, 2012 10:05:43 AM djohn...@desknetinc.com wrote:
 
 This is closer, but still doesn't work correctly if two Misc categories
 are being compared, or one Misc category is compared to itself.
 Try:
 
 @Override
 public int compareTo(Category c) {
 if(category.equals(Miscellaneous)) {
 if(category.equals(c.category) return 0; // correctly
 handle equality.
 else return 1;
 } elseif (c.category.equals(Miscellaneous)) {
 return -1;
 } else {
 return category.compareTo(c.category);
 }
 }

You're right for the general case of compare(), but in my defense I'd like to 
say that merge sort will never compare the same object and the list was 
constrained to one special object, so in this case it'd work for the sort.

But it's likely better to handle the general case just in case someone other 
than the sort uses the compare() so your comment is well taken.  Nothing like 
fixing up one bad behaviour only to replace it with some more obscure one.


-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: This is just plain ... odd.

2012-11-08 Thread Lyallex
 [snip]




 You got the same (wrongish) results since you gave the sort the same order
 in
 the list.  I can't recall how merge sort can freak out when given
 conflicting
 compares, I seem to recall that you might get an endless loop under some
 circumstances as it orders and reorders the same group of objects.


This is all very interesting, no really it is, but it doesn't really answer
the original question
which is that given the same initial data in the same initial order and
executing exactly the same code in the
same release of Java produces different results.

The only difference between the two executions is the fact that the test
code executes in
it's own instance of the JVM whereas the other execution runs in an
instance shared with the container.

I accept that the behaviour may be undefined even though it is consistently
repeatable in both environments
but surely given everything else being equal the results should be the same
... or maybe I'm just losing the plot.

Lyallex


Re: This is just plain ... odd.

2012-11-08 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Lyallex,

On 11/8/12 8:35 AM, Lyallex wrote:
 I thought about posting this to a Java list but I can't reproduce
 it 'standalone' so I thought I'd have a go here.

There's something to that can't reproduce it standalone that you
should be worried about.

 I have a facade that publishes a method that contracts to return a
 list of categories ordered alphabetically

All problems in computer science can be solved by another layer of
abstraction. Sure you can't fit a Proxy to a Service in there?

 My facade calls out to a database server that returns a
 ListCategory in random order. I then call collections.sort on the
 list and return the result.
 
 [ ... ]
 
 If I test this by running a client of the facade I get the expected
 results, the list is ordered as required with Miscellaneous on
 the end
 
 However, and here's the thing, When my app starts an initialisation
 servlet runs, calls the facade method and puts the resulting List
 on the application context. When I render the list via a custom tag
 the list has in some way been altered so that the String 
 Miscellaneous is in it's 'natural' position not what I want at
 all.

What does that custom tag do? A beer says it sorts something. Or,
maybe you have some silly client-side process that sorts the entries
after they are loaded into the browser.

 I have tried everything I can think of to reproduce this behaviour 
 in a standalone Java program but the list is always returned as
 required. When I call the method from a servlet the list is always 
 returned in it's natural order, I know collections.sort is being
 executed as the list is in alpha order, it's almost as if the
 comparator is being replaced in some way

Are you using Collections.sort() or are you using a sorted collection?
If you are calling Collections.sort() then the list is sorted once and
it can be mutated. If you have a sorted list, then the comparator
could conceivably be replaced (but really only by creating a new
Collection).

 I have no servlet filters or any other code 'in the way' between
 the facade and the initialization servlet.

Sounds like the problem is between the application scope and the page.
Custom tag? Secondary sort?

Simple test that doesn't require you to read any of your own code:

Wrap the sorted collection in the application scope with
Collections.unmodifiableList(sortedList). Now you'll get an exception
with a stack trace whenever any code tries to re-sort it.

- -chris
-BEGIN PGP SIGNATURE-
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://www.enigmail.net/

iEYEARECAAYFAlCcNB4ACgkQ9CaO5/Lv0PDLuACgp/C8BkyI0cPOY5YoiwlJHnwe
td0AniTAY+GDt1h1cI45Czj9VMqLuu7U
=HvRr
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: This is just plain ... odd.

2012-11-08 Thread Russ Kepler
On Thursday, November 08, 2012 07:36:20 PM Lyallex wrote:

 The only difference between the two executions is the fact that the test
 code executes in
 it's own instance of the JVM whereas the other execution runs in an
 instance shared with the container.
 
 I accept that the behaviour may be undefined even though it is consistently
 repeatable in both environments
 but surely given everything else being equal the results should be the same
 ... or maybe I'm just losing the plot.

No, you're right but just missing some small difference in the environments.

I'd verify that you get the same input data in the same order in both cases, 
and that you're starting with the same size container and using the same sort, 
etc.  Something is different, if it isn't the data then it has to be in the 
code.  Last time I found something like this is was a replaced class caused by 
a classpath difference - maybe walk the debug and see exactly what is being 
executed in the sort?



-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: This is just plain ... odd.

2012-11-08 Thread Christopher Schultz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Russ,

On 11/8/12 6:05 PM, Russ Kepler wrote:
 On Thursday, November 08, 2012 07:36:20 PM Lyallex wrote:
 
 The only difference between the two executions is the fact that
 the test code executes in it's own instance of the JVM whereas
 the other execution runs in an instance shared with the
 container.
 
 I accept that the behaviour may be undefined even though it is
 consistently repeatable in both environments but surely given
 everything else being equal the results should be the same ... or
 maybe I'm just losing the plot.
 
 No, you're right but just missing some small difference in the
 environments.
 
 I'd verify that you get the same input data in the same order in
 both cases, and that you're starting with the same size container
 [...]

After writing a bench test that I couldn't get to fail, your comment
here tripped a thought in my brain: the container size. So, I added
an element to my list of Strings and boom: failure. It turns out that
the collection size doesn't matter: I just hadn't been iterating
enough, so I added a loop that will run until the initial sorted order
doesn't match the re-sorted order (with shuffles in between).

Lyallex, see the code below: it will fail after a few iterations to
produce the same element ordering. Switch from BrokenSorter to
WorkingSorter and you'll find that it runs forever.

Are you *sure* that your database always returns the items in the same
order? If you plan on sorting alphabetically later, why bother sorting
by id when fetching? Unless you are really sorting by id when
fetching, the data can come back in any order. It may *often* be in
entry-sequenced order, but it is certainly not guaranteed to be.

The code below shows that, without any funny business, the sort can
work sometimes and not in others.

Enjoy,
- -chris

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SortTest
{
public static void main(String[] args)
{
String[] fruits = new String[] {
Apples,
Bananas,
Coconuts,
Dates,
Eggplants,
Figs,
Grapefruits,
Honeydews,
Ilamas,
Jambolans,
Kepels,
Lemons,
Miscellaneous,
Nectarines
};

ListString fruitList = Arrays.asList(fruits);

ComparatorString sorter = new BrokenSorter();

System.out.println(Initial order:  + fruitList);

Collections.sort(fruitList, sorter);
System.out.println(Sort 1:  + fruitList);

ListString saved = new ArrayListString(fruitList);

int i = 1;
do
{
Collections.shuffle(fruitList);
Collections.sort(fruitList, sorter);
System.out.println(Sort  + (++i) + :  + fruitList);
}
while(fruitList.equals(saved));
System.out.println(Stopped after  + i +  iterations because
the list did not sort the same way.);
}

static class BrokenSorter
  implements ComparatorString
{
@Override
public int compare(String a, String b)
{
  if(a.equals(Miscellaneous))
  return 1;
  return a.compareTo(b);
}
}
static class WorkingSorter
  implements ComparatorString
{
@Override
public int compare(String a, String b)
{
  if(a.equals(Miscellaneous))
  return 1;

  if(b.equals(Miscellaneous))
  return -1;

  return a.compareTo(b);
}
}
}
-BEGIN PGP SIGNATURE-
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://www.enigmail.net/

iEYEARECAAYFAlCcj7cACgkQ9CaO5/Lv0PBpawCeORBT62XWcjyw+SruT6Bhkh50
sDEAn1ZjSiPR70+DV/QVBFOjXKjH498o
=F3QS
-END PGP SIGNATURE-

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org