Bug 61004 - HSSFColor depends on java.awt.Color which is not available on Android and Google App Engine
Summary: HSSFColor depends on java.awt.Color which is not available on Android and Goo...
Status: NEW
Alias: None
Product: POI
Classification: Unclassified
Component: HSSF (show other bugs)
Version: 3.16-dev
Hardware: Other other
: P2 normal (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-04-18 19:22 UTC by rahul.herwadkar
Modified: 2017-06-16 20:17 UTC (History)
0 users



Attachments
Excel file generated from POI APIs (69.50 KB, application/x-ole-storage)
2017-04-18 19:22 UTC, rahul.herwadkar
Details

Note You need to log in before you can comment on or make changes to this bug.
Description rahul.herwadkar 2017-04-18 19:22:51 UTC
Created attachment 34925 [details]
Excel file generated from POI APIs

The following code example works fine with poi-3.15-20160924.jar on Google App Engine environment:

  private static CellStyle newCellStyle( Workbook oWorkbook )
  {
    CellStyle oCellStyle = oWorkbook.createCellStyle();
    oCellStyle.setBorderBottom(BorderStyle.THIN);
    oCellStyle.setBorderTop(BorderStyle.THIN);
    oCellStyle.setBorderLeft(BorderStyle.THIN);
    oCellStyle.setBorderRight(BorderStyle.THIN);
    oCellStyle.setAlignment(HorizontalAlignment.CENTER);
    oCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
    oCellStyle.setWrapText(true);

    return oCellStyle;
  }

The same code throws java.lang.NoClassDefFoundError error with latest poi-3.16-20170419.jar:

Error for /betacapm 
java.lang.NoClassDefFoundError: java.awt.Color is a restricted class. Please see the Google App Engine developer's guide for more details.
 at com.google.apphosting.runtime.security.shared.stub.java.awt.Color.<clinit>(Color.java)
 at org.apache.poi.hssf.util.HSSFColor$HSSFColorPredefined.<init>(HSSFColor.java:113)
 at org.apache.poi.hssf.util.HSSFColor$HSSFColorPredefined.<clinit>(HSSFColor.java:55)
 at org.apache.poi.hssf.model.InternalWorkbook.createExtendedFormat(InternalWorkbook.java:1450)
 at org.apache.poi.hssf.model.InternalWorkbook.createCellXF(InternalWorkbook.java:921)
 at org.apache.poi.hssf.usermodel.HSSFWorkbook.createCellStyle(HSSFWorkbook.java:1326)
 at org.apache.poi.hssf.usermodel.HSSFWorkbook.createCellStyle(HSSFWorkbook.java:123)
 at com.betacapm.api.PortfolioWorkbook.newCellStyle(PortfolioWorkbook.java:163)

My use case is to create an Excel spreadsheet. As mentioned before, this use case works with POI v3.15 in the Google App Engine environment, but breaks with v3.16.

I had encountered a similar issue when I migrated from v3.13 to v3.14. See bug https://bz.apache.org/bugzilla/show_bug.cgi?id=59194 for details. This was fixed in v3.15.

There are no Jetty jars in my GAE setup. Outside of the default GAE jars, this is what I package into my app:

commons-codec-1.10.jar
commons-lang3-3.5.jar
commons-logging-1.2.jar
commons-math3-3.6.1.jar
gson-2.8.0.jar

Currently, my only workaround is to revert to v3.15.

Attachment Stocks.xls shows a sample Excel fie created with POI apis.
Comment 1 Nick Burch 2017-04-19 05:37:32 UTC
It looks to me like we're using java.awt.Color just as a friendly way to store and retrieve RGB values, as well as looking up some pre-defined colour values.

I think it might be fairly quick to replace that with a custom RGB class, but I'll defer to others to check/confirm/etc
Comment 2 Javen O'Neal 2017-04-19 08:23:34 UTC
Do we need to make an effort to exclude java.awt.Color or java.awt.* from our codebase if we want to support restricted environments?

If this is a commitment that we can and want to make, we should add the appropriate rules to forbidden apis. This would keep this behavior from lapsing back once fixed (we already fixed this before in bug 59194).

If I remember correctly, HSLF relies on java.awt for positioning of shapes and rendering of slides, so running HSLF in a restricted environments is less likely. HSSF might not have the same quantity of java.awt usages.

Perhaps this discussion should take place on the dev list.
Comment 3 Nick Burch 2017-04-19 08:48:32 UTC
I think the agreement from last time was that we'd make small/minor changes to support common alternate environments like GAE, but we wouldn't re-write huge swathes (though we might accept patches that do). Generally major re-packaging / tweaking needs to happen elsewhere, eg the .Net port or the Android with the centic9/poi-on-android rework

So, that'd probably mean we wouldn't re-do lots of the HSLF/XSLF stuff, but we'd entertain a small (eg 1-2 class) tweak where possible. We can't easily exclude AWT from all of the SpreadSheet stuff though, as some parts (eg drawing or font size calculations) require it heavily + couldn't be easily changed to do without it.
Comment 4 Javen O'Neal 2017-04-19 10:15:06 UTC
(In reply to Nick Burch from comment #1)
> It looks to me like we're using java.awt.Color just as a friendly way to
> store and retrieve RGB values, as well as looking up some pre-defined colour
> values.
> 
> I think it might be fairly quick to replace that with a custom RGB class,
> but I'll defer to others to check/confirm/etc

This regression was the result of completely rewriting the HSSFColor class from a bunch of singleton subclasses of HSSFColor to instances of HSSFColor that are stored in an enum. This was a much needed change.

This also hopefully puts us in a little better position to differentiate between predefined colors, indexed colors, and custom colors.

Using java.awt.Color is a natural way to store the rgb triplet, and will accommodate future code consolidation with XSSFColor, which also supports alpha transparency and transformations (HSB, brighter, darker).

If someone cares to author a patch for HSSFColor without java.awt.Color, using either int and o.a.p.util.BitFields, 3 shorts, or a short[3] to store the rbg, I'd be willing to review it, though please keep the XSSFColor merge in mind.