Can’t Serialize JFreeChart Chart?

I was getting a serialization exception when I tried to serialize a JFreeChart chart to a file. The error message and corresponding stacktrace offered little in the way of clues. I finally figured out that the problem was with an interface implementation I had set for generating custom legend item labels. I used a lambda expression to supply the interface (XYSeriesLabelGenerator) implementation. Alternatively, one might use an anonymous inner class to provide the implementation. Neither of these approaches will work, as it is not possible (as far as I know) to implement the Serializable interface for the implementation. So, I used the good, old, named top-level class:

Source Code for CustomSeriesLabelGenerator

XYItemRenderer renderer = ...;
        new CustomSeriesLabelGenerator());

So, if you are getting an error when serializing a JFreeChart chart, check how you have passed any interface implementations into a setter… that may be the problem.

JFreeChart Tool Tips for Multiple Data Series

In a JFreeChart x-y scatter chart I have two series of data. I needed to add custom tool tips CustomXYToolTipGenerator for each series. The first approach I tried I never was able to get it to work:

XYPlot plot = ...;
XYItemRenderer renderer = plot.getRenderer();
List<String> tips1 = ...;
List<String> tips2 = ...;
CustomXYToolTipGenerator tipGenerator1 =
        new CustomXYToolTipGenerator();
CustomXYToolTipGenerator tipGenerator2 =
        new CustomXYToolTipGenerator();

The tool tips for the first series would work, but there would be no tool tips for the second series.

Luckily, there is a second approach, which worked:

CustomXYToolTipGenerator tipGenerator =
        new CustomXYToolTipGenerator();

If I ever figure out why the first approach did not work, I will update this post. If anybody has an idea, please leave a comment! Thanks!

Custom XY Tool Tip Generator in JFreeChart

Using JFreeChart I added a custom xy tool tip generator to a scatter plot:

JFreeChart chart = ChartFactory.createScatterPlot( ... );
XYPlot plot = chart.getXYPlot();
XYItemRenderer renderer = plot.getRenderer();
CustomXYToolTipGenerator tipGenerator =
         new CustomXYToolTipGenerator();
List tipsMain = new ArrayList<>();

I then populated the data for the series and the tool tips:

XYSeries series1 = new XYSeries("S1");
for (TechBundle bundle : techBundles) {
    double cost = bundle.getCost();
    double fe   = bundle.getFE();
    series1.add(cost, fe);
    tipsMain.add(String.format("%s $%.0f %.2f",
            bundle.getBundleID(), cost, fe));

The problem was the tool tips were not correct for the point. Tool tip for point n would be shown for point m.

This is due to the fact that by default the xy series is automatically sorted (in ascending order of x-values). That sorting messed-up the alignment of the data and the tool tips. The fix is to turn-off the automatic sorting, which must be done when the series is constructed:

XYSeries series1 = new XYSeries("S1", false);

Copy a file from AWS S3 to an EC2 instance

My goal was to successfully copy a file I had stored in a Amazon Web Services (AWS) Simple Storage Service (S3) bucket to an Elastic Compute Cloud (EC2) instance I had created.  I ran into some problems. I hope documenting my experience will help someone else. Or perhaps, as is often the case, only I seem to be able hit these kinds of problems.

I used the Amazon Linux machine image when I created my EC2 instance. The nice thing about a Amazon Linux flavored EC2 instance is that the AWS Command Line Interface (CLI) comes pre-installed.

When I issued a “aws s3 ls” command on my EC2 instance I received an error message. The error I encountered was stated as follows.

A client error (SignatureDoesNotMatch) occurred when calling the ListObjects operation: The request signature we calculated does not match the signature you provided. Check your key and signing method.

I had created an IAM user and gave that user full access for S3.

Using “aws config” I stored the IAM user’s secret access key (and key ID) in the AWS Command Line Interface (CLI) configuration file (~/.aws/config).

I initially thought that maybe there is some connection between the IAM user and the EC2 Linux user. I had logged into he EC2 instance using the “root” user (ec2-user).

A thought hit me that maybe the “trick” was to use a named profile (in the AWS CLI configuration) where the name of the profile matches the IAM user name. So, I tried that and it worked! I was ready to give myself the Genius award, but then I changed the profile name so that it didn’t match the IAM user name. Things (e.g., “aws s3 cp”) still worked. Hmmm… maybe I am not a genius… my wife certainly thinks quite the opposite. So, then I went back to what I had tried before (just putting the access key data for the IAM user in the [default] section of the ~/.aws/config file) and that worked!

The only thing I can think that might have made a difference is I had stopped and restarted the EC2 instance prior to getting things to work.

I also added a region=us-west-2 line to the ~/.aws/config file, but previously I had tried specifying the region using the –region command line option. So, I doubt adding the region to the config file made a difference, but I’ve been surprised before.

Anyhow, the bottom line is:

  • I can log in to my EC2 instance as ec2-user and then use the access key of a IAM user to execute “aws s3” commands
  • There is no connection between the IAM user and the EC2 Linux user.

I hope these ramblings help someone in the future. If so, please leave me a comment. Thanks!


Welcome to my site

Welcome to my humble, little site. Currently this site is a very much a work in progress. I plan to use this site to blog about programming in Java and related topics.

I have a BS degree in Mechanical Engineering from Penn State University and a MS degree in Mechanical Engineering from Purdue University. However, I have spent most of the 25+ years since college developing software. Initially the software I developed was simulation software for engineering, but I have since worked on many other types of software.

I currently work at Scenaria.