billroper: (Default)
2016-09-09 11:21 pm
Entry tags:

Fun With Weak References

I think this is clever. Your mileage may vary.

So in our Java Server implementation, when you authenticate with the Server, we create a Session object, put it into our Session Catalog, and pass back either a String that is the session ID or the actual Session object, depending on what environment you're operating in. The Session implements HttpSessionBindingListener so that it will get a callback when the bound Session is being destroyed. When we get the callback, we take the Session out of the Session Catalog, which should, in theory at least, be the last strong reference to the Session object.

We may have opened a number of objects of different types on behalf of the Session. Each type of object has its own Catalog, which -- in this case -- is stored in a static WeakHashMap where the Session is the key and the Catalog of objects opened on behalf of that Session is the stored value. So when the Session is headed off to the Garbage Collector, we'll also garbage collect the Catalog of objects that was associated with it in the WeakHashMap.

The advantage of this approach is that when I add a new type of object to the system that I want to open on behalf of the Session, I don't have to change the Session object. I just have to create a static WeakHashMap that holds all of the Catalogs for the new object type. This also puts all of the Catalog information in the place where I'd like it to be, given the general architecture of the Java Server. In this case, the Catalog classes are all inner classes inside of the object class that they hold.

As I said, I think it's clever... :)
billroper: (Default)
2016-04-05 11:11 pm
Entry tags:

The Invisible Bug

It was one of those days, at least in some respects.

I had fixed a number of bugs and ported a bunch of code fixes from C++ to Java. But there was an intractable bug that turned out to be due to corrupted data in one of my classes. In fact, what I was seeing was that the child class was pointing back to the wrong parent as its owner.

So it seemed that something had to be wrong with either the copy constructor or the clone() method in my Java code. And I stared at them. And stared at them.

And about a half-hour after I'd started staring, I suddenly realized that I was setting the parent of the children incorrectly when I was cloning the parent class. Because you don't set the parent to this, you set the parent to the newly created parent.

I could easily have stared at that for a lot longer before figuring out that I had typed something witless.

*sigh*

On the other hand, the bug appears to have gone away now.
billroper: (Default)
2016-04-04 10:58 pm
Entry tags:

Bill vs. The Obscure Documentation

In one of those things that surprised me, it appears that there's no one in our group who really understands how to configure a WebLogic WorkManager -- either the one that is integrated into JDeveloper or the standalone version. The problem is that the default WorkManager will run wild if we hand it a large consolidation to run and will gleefully consume all of the available resources on the machine, so I really need to put some constraints on the process. And while I could try to put those in front of the WorkManager calls, the right place to put them is into the running WorkManager.

If only I knew how to do this. And I applied an awful lot of Google-fu to the process, but -- although there are many places that reference the constraints and sort of talk about how they work -- there isn't really a good set of examples for how to implement them.

Eventually though, I found enough breadcrumbs that I was able to figure out how to get this working in JDev. And once I figured that out, I was able to translate things out into the standalone WorkManager.

I'm sure there are a number of improvements that we can make to my configuration.

But this will do for today.
billroper: (Default)
2016-03-21 11:00 pm
Entry tags:

The Wretched Incompatibility of Things

For testing, I've written a Java implementation of MFC serialization. We won't be shipping it, but it allows us to test things for now.

The problem is that Java and C++/MFC have very different ideas about how to handle various data items. For example, Java would like IDs to be immutable and shared among different objects that reference the same object by that ID. C++ doesn't want to share those IDs, because reference counting, well, not so much. So if you edit something in Java, the course of least resistance is to share the IDs, but then you need to make them all unique when you serialize them so that they work the way that C++ expects.

This turns out to be more difficult than you might think.

*sigh*
billroper: (Default)
2016-01-14 11:09 pm
Entry tags:

Factor Three

It's being like that today. I had intended, at some point, to rewrite the entity data handling on the new Server architecture. Sadly, the current entity data handling is causing our consolidation to run out of memory, so I really need to rewrite it now.

The good news is that -- after a brief false start -- I have figured out how to structure things so that they work in a fashion that's similar to everything else on the Server that requires locking. The locking itself still needs some work for a clustered environment, but that's something that can be replaced in one swell foop once we get everything else straightened out. Since we're not yet running clustered, the current locking will do for the moment.

The amusing thing is that I have finally found a place where using a WeakHashMap is the right answer. :)

I'll still be cleaning this up tomorrow morning, but there is a non-train light at the end of the tunnel.
billroper: (Default)
2016-01-07 06:25 pm
Entry tags:

We May See Murder Yet

Yesterday's intractable problem at work certainly appears to be a Java bug.

Take, for example, the case where you have wrapped an InputStream inside an InflaterInputStream -- in this case, an InputStream that is actually an OracleBlobInputStream, although it fails equally well should you be connecting to SQL Server. This should, in theory, allow you to read a compressed BLOB out of a database table. And as long as you are calling the read() method with no arguments and reading the stream one byte at a time, it does.

Reading the stream one byte at a time is not the most efficient way of handling it though, especially when you know that the next thing that is on the stream is a byte array of a particular length. In that case, you would like to use the read( b, off, len ) method on the stream so that you can read multiple bytes from the stream in one operation. In fact, you should be able to set the offset to 0 and the length to the length of the array and you can do this in one beautiful call.

Most of the time.

There's something that's busted inside the native code implementation of Inflater.inflateBytes so that it can't manage to make this work all of the time. I strongly suspect that it hits a boundary between blocks that the Deflater wrote out and just stops in mid-read so that a call that should return, say, 53 bytes of data only returns 10 bytes. The rest of the data is there, but your read( b, off, len ) method simply isn't going to let you have it.

I apparently ran into this problem in June of 2014 and coded around it at the time by reading the byte array one byte at a time. But then I forgot about it and wrote some more code that gleefully tries to read the byte array in one operation.

And it works.

Most of the time.

Sadly, most of the time is not nearly good enough.

*mutter* *mutter*
billroper: (Default)
2016-01-04 10:23 pm
Entry tags:

Hi Ho! Hi Ho!

Vacation being over now, it was time to get back to work.

Today, I fixed a flawed Comparator that I'd copied from the C++ code and not modified quite correctly. And I refactored some other code that was failing so that it behaves in a more Java-like fashion and no longer fails in the way that it was failing before.

Tomorrow, who knows?
billroper: (Default)
2015-12-10 10:30 pm
Entry tags:

Handling It

So I'm working on setting up an API for some of the user-interface guys to use to access our data on the server. This frequently involves them sending in an assortment of Strings that uniquely identify some object so that we'll open it and cache it for them to access repeatedly. And when they want to access it again, they'll send me that sequence of Strings again and I'll find what they're looking for.

It strikes me that life would be much more efficient if I gave them a unique handle to the object that they've opened so that they can reference it by the single String that would contain the handle. I've sent them an e-mail proposing this.

We'll see what they say in the morning.
billroper: (Default)
2015-11-23 10:10 pm
Entry tags:

The More You Know: JSON Edition

Having been tasked to generate some JSON in Java, I went out looking for tools, because I hate dealing with the trivia of punctuation. :)

I found the JsonWriter which generated correctly formed JSON.

Slowly. Very slowly. As in, it took about seven seconds to format 18,000 cells of data based on my rough count as it ran in the JDev debugger.

Not surprisingly, folks were not exactly thrilled with that report.

So I did some more research today. It turns out that JsonWriter constructs a JSON structure in memory, much like DOM does for XML. If you've got an itty-bitty structure, this is just fine. If you have large structures, not so much.

Happily, there is a streaming JSON API via the JsonGenerator interface. It plunked out the same 750K of data in less than a second. The limiting factor no longer appears to be the speed with which I can generate the JSON, but rather the speed with which I can retrieve the data and convert it from numeric to string format.

I like streaming APIs...
billroper: (Default)
2015-10-16 11:55 pm
Entry tags:

Another Java Learning Experience

So one of the other programmers in the group thought he'd found a bug in some of my code. I asked if he could set up a screen share so that I could watch him step through the failing code. And after a little bit of research, I recoiled in horror.

In some code that I had written fairly early in my Java development, I had pretty grotesquely mishandled the immutable DateTime class from the Joda Time package. I'd called a method on a DateTime that would return a new DateTime, but I hadn't assigned it to anything, with the net result that it pretty much did nothing. Since I wanted it to do something, that was a bad thing. Apparently, I'd assumed I was modifying the immutable class.

Not so much.

So I fixed that and then went on a snipe hunt through the rest of the code to find the places where I'd used the library badly. There were only a couple of actual bugs, but there were several places that I could -- and now have! -- improved things substantially.

I guess the good news is that I'm learning. :)
billroper: (Default)
2015-09-24 11:09 pm
Entry tags:

Huge Tracts of Code

I was writing a new interface layer in Java 7 today where I'm being handed a bunch of key/value pairs to use to look up and return various items of data.

So I wrote an immutable class with a constructor that processes the key/value pairs and loads up the keys into the correct locations in the object.

But I need to sort the queries so that all of the Key A queries are grouped together and all of the Key B queries are grouped together within the Key A queries. So I wrote a compareTo method for the immutable class that works through all of the data elements in the class, starting with Key A, then Key B, working down through Key N. Then I tossed the keys into a TreeSet, which happily sorted them so that when I walk through the elements, all of the matching values for Key A come first, all of the matching entries for Key B within Key A come next, and so on.

Then I created a class that would load an instance of the big in-memory dataset that Key A refers to. And I wrote a moderately long switch/case statement for each of the different kinds of data that I might return from the big dataset based on the original class that loaded up all of the key/value pairs.

I think this might work.

Of course, I still have to test it... :)
billroper: (Default)
2015-09-21 10:12 pm
Entry tags:

Things That Should Work Better

Wonderful. I can't check his test case in my code, because when I try to save the file with my changes in it, the serialization code that he wrote for some other stream in the document writes stuff that can't be read by the old code which is the only place that I can reliably look at the output data.

Meanwhile, his test case continues to fail after all of my changes.

Blargh.
billroper: (Default)
2015-09-09 11:06 pm
Entry tags:

One Thing Leads to Another

It turns out that the editing / updating code for one of my Java classes is an unhappy camper. So I set out to fix it.

In order to make it faster, I refactored the class to use a map for looking up entries. This wasn't too complex. Unfortunately, once I got all that code updated, it still didn't work, producing a null pointer exception in some other class.

So I fixed that class so that we weren't generating the null pointer exception.

This led into yet another class that was behaving badly. My only excuse for this was that it had been a templated class in C++ that I had to write without generics in Java, because it uses native data storage. So I fixed it.

There is still something wrong in there somewhere.

I will find it in the morning.
billroper: (Default)
2015-09-03 11:13 pm
Entry tags:

Sooner or Later

Sooner or later, I will get to the bottom of this mass of C++ changes that need to be ported to Java.

Sooner would definitely be better than later...
billroper: (Default)
2015-07-29 10:23 pm
Entry tags:

Missed It By *That* Much

Because I did a lot of the early code for our Java port as a proof of concept, the porting was not as systematic as I might have hoped, because I needed to demonstrate that various bits and pieces worked as I went, rather than pulling the whole thing over in one huge operation. This had advantages and disadvantages.

The advantage was we could see things working.

This disadvantage was that one of our major subsystems only got ported as a skeleton.

I have spent the last week and a half putting meat onto that skeleton, which involved a major rewrite of some fifteen year old code of mine.

Happily, I am better at design and coding than I was fifteen years ago. But the rewriting is killing me.

There is a light at the end of the tunnel. I am fairly sure it is not a train. :)
billroper: (Default)
2015-03-18 09:53 pm
Entry tags:

Well, That's Better

Today at work, I found out things that no one else in our group knew about how to configure a CommonJ WorkManager in WebLogic. I also determined that we should be able to obtain a CommonJ WorkManager from WebSphere, so all things ought to operate properly if we actually go to the trouble of setting them up.

Now, if we can just get little girls to go to bed, we will have achieved a victory condition.
billroper: (Default)
2015-03-11 10:48 pm
Entry tags:

It's a Learning Experience

As I continue to work on the mass of Java code that I've developed, the next step is to consider writing some JUnit unit tests. Or perhaps, more than just consider it, because they're really going to be necessary.

Fortunately, the Job/Task pair of related classes makes an excellent tackling dummy for learning how to do this, as they're pretty much completely isolated from the rest of the world, so they don't need much to make them run.

Except that I need a WorkManager to actually run the Job. And for that, I have to get the JUnit unit test to run inside of WebLogic. Eep!

Today, I spent some time figuring out how to run the JUnit tests inside of JDeveloper using the built-in support there. That seems to be going well, in that the tests actually ran and succeeded and produced the success / failure report that I was supposed to see.

It looks like I may be able to set up the WebLogic bits by using the Apache Jakarta Cactus package.

Which is tomorrow's problem.

In the meantime, I think I'll go find [livejournal.com profile] daisy_knotwise and watch Agents of SHIELD. :)
billroper: (Default)
2015-02-23 09:53 pm
Entry tags:

OK, Maybe It *Is* That Simple

Today at work, I went back to hacking around with the code that I had been working on last Friday. I sent an e-mail out to the group, gleaned some more information about how they wanted the logging implementation to work, patched in the database persistence code, and got something that is frighteningly close to a complete system.

We still need to finish the database persistence code (there's another fellow who actually pulls all of that together) and I still need to fill out a couple of more functions in my standard boilerplate for classes that are persisted in the database, but this is actually nearly ready to be tested.

Save for the pesky absence of an actual logging implementation to link in with the system. But we can sort that out tomorrow. :)
billroper: (Default)
2015-02-20 07:06 pm
Entry tags:

This Has Got To Be a Trap

Several weeks ago, I started looking at the WebLogic WorkManager to use for managing some multithreading operations that I'm working with for our Java POC. Now, I have the advantage of having written our original multithreading architecture in C++, so I'm not unfamiliar with the problem.

At about three o'clock this afternoon, I picked up the documentation again and decided to try to start coding to the interface. By 6 PM, I had the better part of the architecture set up to support what we want to do in multithreading.

I have either drastically misunderstood something or this is easier than I thought.

Or maybe I'm just good at this...

But earlier today, I'd estimated this as a three week task. Mind you, I still have to add all the error handling and a little bit more boilerplate, but I think I should be able to test this architecture on Monday and see if it's sane.

Yoicks!
billroper: (Default)
2014-11-26 11:54 pm
Entry tags:

A Success on the Road

The demo today went well. There's still a ton of work to do, but it's progress.