Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
horse_ebookmarklet
Oct 6, 2003

can I play too?
Given the following conditions:
code:
		double anArray[] = {9.2, 9.3, 9.0, 9.9, 9.5, 9.5, 9.6, 9.8};
		double lowest = 10, highest = 0, sum = 0, fin;
		for(int i = 0; i < anArray.length; i++) {
			if(anArray[i] < lowest) { lowest = anArray[i]; }
			if(anArray[i] > highest) { highest = anArray[i]; }
			sum = sum + anArray[i];
		}
		fin = (sum - highest - lowest);
		System.out.println( fin );
fin is equal to 56.90, but the application prints 56.89999999999999; Is this due to a quirk in Java's System.out class? What should I do in a case such as this when I want to print a double?

Adbot
ADBOT LOVES YOU

horse_ebookmarklet
Oct 6, 2003

can I play too?

Incoherence posted:

It's a floating point quirk. If you HAVE to have 56.9 for some reason, round it.
Well then this becomes irritating on two levels. I guess I can sorta understand a floating point quirk in Java, but why the hell did Eclipse decide to be inconsistent and represent the value as 56.9 in it's debugger? Oh well. Thanks for the help!

horse_ebookmarklet
Oct 6, 2003

can I play too?
What are the cool kids using these days for an MVC Framework? Struts 2 + Hibernate?
I've been playing around with the Spring + Hibernate and it seems to be pretty nice.

horse_ebookmarklet
Oct 6, 2003

can I play too?
When I annotate a method/field/parameter/type, where are is the annotation's equals and hashcode defined? I'm digging through the OpenJDK sources and I can't figure it out.
I'm curious to see the definition of equals() and hashCode(), as we're getting into a slapfight with our JVM vendor on what logical equivalence is. In HotSpot, it seems a normal annotation instance (via .getAnnotations()) can be logically equivalent to a user defined implementation of that annotation interface (AnnotationImpl implements OurAnnotation), but in our production JVM they can't be.
This problem, of course, manifested itself as crazy undefined behaviors when working with HashMaps.

horse_ebookmarklet
Oct 6, 2003

can I play too?

rhag posted:

I don't think I understand.
So, you have @OurAnnotation, and a class that implements it, AnnotationImpl. All good so far. You can implement in AnnotationImpl hashCode and equals without a problem. However ... what does that have to do with the HashMap? Are you storing annotations in a HashMap? Or ... how does this is supposed to work then?

We are storing them in HashMaps, which is how I discovered the problem, and not really the problem itself. The hashmap is calling equals() which I believe is behaving incorrectly.

Amarkov posted:

Annotations inherit equals() and hashCode() directly from Object, and AccessibleObject.getAnnotations() is not specified to ensure reference equality with anything else. I'm also not quite clear on what you're trying to do, but I think the right answer is to override those two methods.

I'm not attempting to check reference equality, I'm attempting to check logical equality using .equals().

My AnnotationImpl implements equals and hashCode per the description in the Javadoc. The @OurAnnotation that the runtime creates seemingly doesn't implement equals properly. With a known "logically equal" annotation, the runtime equals() returns false. In the AnnotationImpl we created equals() returns true. In the Oracle JVM, both return true as expected.

I'm looking for either a specification or a reference implementation in the OpenJDK of equals() and hashCode() for Annotations. Our JDK vendor is saying that its implementation defined, which doesn't seem correct.

horse_ebookmarklet
Oct 6, 2003

can I play too?
It is an instance of an implementation of the same type, with the exact same properties. The annotationType()s of both return the same class.

I don't know if that javadoc describes the specification or an implementation, which is the point of contention with our vendor. Thats why I'm either looking for a real spec, or something in the OpenJDK reference implementation.

Why? At startup we scan a .properties file and create annotations based off the .properties keys. These annotations and their values are inserted into a hashmap. Later, after we create a new instance of something, we call a static method that scans for Fields that have annotations. If that field's annotation is in the hashmap we set that field equal to the value in the map. Its pretty crude, and could be replaced with a real DI framework.

So I could change it, but if its technically allowable via specification or reference implementation I'd rather our vendor fix their JVM.

horse_ebookmarklet
Oct 6, 2003

can I play too?

Max Facetime posted:

What ends up being called on my machine is a package-visible class sun.reflect.annotation.AnnotationInvocationHandler and its equalsImpl() method. This is called by a runtime generated proxy-class ($Proxy3) instance which marks one location that was annotated in the source code.

There's something weird in the equalsImpl() method. It has a check to see if the other object can be treated :airquote: as one of us :airquote: but if not it does a member-wise compare anyway. This smells of something.

Then Java 7 API docs say

Annotation.equals() posted:

Returns true if the specified object represents an annotation that is logically equivalent to this one. In other words, returns true if the specified object is an instance of the same annotation type as this instance
and

Annotation posted:

The common interface extended by all annotation types. Note that an interface that manually extends this one does not define an annotation type.

So my reading is that if you are mixing your own classes implementing Annotation and generated Annotations then the Oracle implementation is wrong if it says generated Annotations are equal to subclasses of Annotations.
I'm not sure what our JVM is doing, as it is off in native land the whole time. I'm looking into running it fully interpreted mode, but there are a bunch of weird considerations (No filesystem, no dynamic loading, etc). This is why I want to make this the vendor's problem!

I've highlighted what I think are some keywords.
I think this example qualifies as being of the same annotation type. annotationType() returns the same Annotation, and doing an instanceof comparison with our implementation returns true. (Even in our vendor's JVM).
I don't think I'm violating the second rule either. No inheritance is going on, just a direct implementation.

rhag posted:

What actually he needs to use is the MapBinder or Multibinder from Guice.
The usage of annotations in this case looks a bit ... weird to say the least, but there could be a solution (kind of):

You read properties from a properties file. That is, key,value pairs. You can store that anywhere (in a map, properties file or simply a resource bundle). Now, via reflection you scan for fields, and you look for certain annotations (you have to know what annotations you're looking for). Then you can read the properties of that annotation (value, or whatever other things it may have), and then do whatever you need to do (update the field's value for example).

Even in your "not invented here" approach, you still don't need to store annotations in a map. Don't think of annotations as POJOs, think about them as metadata (which they are). An annotation doesn't make any sense nor does it have any reason to exist (logically) if not applied to a class, field or method.

But really, just use a CDI library (google's guice is lightweight and easy to setup and work with, you don't need to call the big boys like spring or weld).
I agree, It would be pretty easy to rewrite it to simply store the key-values instead of annotation(key)-value. Thats likely what we're going to end up having to do.

I wrote a test case in Guice where I in a module bind(String.class).annotatedWith(Names.named("value")).toInstance("someValue")
I attempt to inject it to a class using Guice.createInjector(theModule).getInstance(TestClass.class);

Under Oracle JVM (6, 7), it works. Under our JVM, I get this really pretty error saying that it value wasn't bound :iiam:
I had to use the -no_aop version, so hopefully that doesn't matter. I'm going to see if I can lob Guice's unit tests over to our environment, but they seem pretty hueg.

horse_ebookmarklet
Oct 6, 2003

can I play too?
So our vendor ended up changing their implementation, wo! It now sounds like I convinced them to do something incorrect, but at least its consistent with the Oracle implementation. It sounds worthwhile to change our implementation anyway, though.
If Guice does canonicalize, I'm not sure why it isn't working! Guice names work now with a patched equals.

horse_ebookmarklet
Oct 6, 2003

can I play too?
I'm confused about CancelledKeyExceptions and a SelectionKey when using NIO Selectors.
I have a situation where an underlying socket channel may be closed by any thread. In a thread separate from where a channel is cancelled, I am calling select() with channels that are registered with OP_READ.
Occasionally I get a CancelledKeyException when I test isReadable(). Clearly another thread is closing a socket channel after select() has returned but before I test isReadable().

I believe my best course of action is to catch a CancelledKeyException. My only concern is that this is an unchecked runtime exception, which would seem to indicate a unrecoverable condition or programming error on my part...
Some references on stack overflow suggest testing isValid() && isReadable(), but this has an obvious time-of-check-time-of-use error.

Other than catching an unchecked exception, I do not understand how else to detect and recover from this condition.

Adbot
ADBOT LOVES YOU

horse_ebookmarklet
Oct 6, 2003

can I play too?
As a stop gap I am catching and recovering from the RuntimeException. It seeeeems to work.

The application architecture currently has a thread where the selector parses tasks (Over TCP) and submits the tasks to a queue, and a number of workers in a pool poll for these tasks. Similar to the architecture suggested.

The tasks are computations that are sent back to the client that requested it. When the task is complete the worker attempts to write the result back to the TCP socket. A client can submit multiple tasks to be computed simultaneously, so multiple workers can write back. I have a wrapper around the SocketChannel that handles synchronization and currently closes the socket channel if something unexpected happens (write() failure or application specific event in the worker).

It sounds like it would be better design to signal the selector thread to close the socket. Next time the selector returns, 'reap' any socket channels that have a 'close pending'.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply