Usage of Marlin in Java Web Start applications

85 views
Skip to first unread message

Botond Kósa

unread,
Mar 27, 2015, 7:18:10 AM3/27/15
to marlin-...@googlegroups.com
Hi!

We are working on a GPS tracking application that is deployed to the users via Java Web Start (JWS). I tried Marlin when run from the command line at it worked as a charm. However, according to the JNLP specification, no bootclasspath entries can be specified when running an application with JWS. Is there an alternate way to enable the use of Marlin renderer?

Regards,
Botond

Botond Kósa

unread,
Mar 27, 2015, 7:22:56 AM3/27/15
to marlin-...@googlegroups.com
See this rejected enhancement request regarding JWS and bootclasspath:

Botond Kósa

unread,
Mar 27, 2015, 7:32:29 AM3/27/15
to marlin-...@googlegroups.com
I also tried adding the marlin jar to the regular classpath and loading the renderer class with Class.forName("org.marlin.pisces.PiscesRenderingEngine") before setting the sun.java2d.renderer property. This failed with the following error:

Fatal error, unable to start iTrack-client because of following exception:
java.lang.SecurityException: Prohibited package name: java.awt.geom
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:659)
at java.lang.ClassLoader.defineClass(ClassLoader.java:758)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:260)
at com.idata.sattracker2.SatTracker2.main(SatTracker2.java:611)

Could putting the FastPath2D class in another package resolve the issue?

Andrea Aime

unread,
Mar 27, 2015, 7:37:21 AM3/27/15
to marlin-...@googlegroups.com
On Fri, Mar 27, 2015 at 12:22 PM, Botond Kósa <boton...@idata.hu> wrote:
See this rejected enhancement request regarding JWS and bootclasspath:


I'm afraid there is nothing you can do, Marlin replaces a core part of the JRE and
that is intentionally protected from application to change, only the
physical user of the JVM can install the files inside the JRE and thus assume
the responsibility for the consequences (Marlin is fine, but in general,
random jars installed in the JRE could be malicious/viruses and so on).

On the bright side, it seems Marlin is going to be merged into JDK 9, so in
the future is should become the default rasterizers, for at least OpenJDK

Cheers
Andrea

--
==
GeoServer Professional Services from the experts! Visit
http://goo.gl/NWWaa2 for more information.
==

Ing. Andrea Aime 
@geowolf
Technical Lead

GeoSolutions S.A.S.
Via Poggio alle Viti 1187
55054  Massarosa (LU)
Italy


AVVERTENZE AI SENSI DEL D.Lgs. 196/2003

Le informazioni contenute in questo messaggio di posta elettronica e/o nel/i file/s allegato/i sono da considerarsi strettamente riservate. Il loro utilizzo è consentito esclusivamente al destinatario del messaggio, per le finalità indicate nel messaggio stesso. Qualora riceviate questo messaggio senza esserne il destinatario, Vi preghiamo cortesemente di darcene notizia via e-mail e di procedere alla distruzione del messaggio stesso, cancellandolo dal Vostro sistema. Conservare il messaggio stesso, divulgarlo anche in parte, distribuirlo ad altri soggetti, copiarlo, od utilizzarlo per finalità diverse, costituisce comportamento contrario ai principi dettati dal D.Lgs. 196/2003.

 

The information in this message and/or attachments, is intended solely for the attention and use of the named addressee(s) and may be confidential or proprietary in nature or covered by the provisions of privacy act (Legislative Decree June, 30 2003, no.196 - Italy's New Data Protection Code).Any use not in accord with its purpose, any disclosure, reproduction, copying, distribution, or either dissemination, either whole or partial, is strictly forbidden except previous formal approval of the named addressee(s). If you are not the intended recipient, please contact immediately the sender by telephone, fax or e-mail and delete the information in this message that has been received in error. The sender does not give any warranty or accept liability as the content, accuracy or completeness of sent messages and accepts no responsibility  for changes made after they were sent or for other risks which arise as a result of e-mail transmission, viruses, etc.


-------------------------------------------------------

Botond Kósa

unread,
Mar 27, 2015, 11:58:37 AM3/27/15
to marlin-...@googlegroups.com
Thanks for the reply. It would be really great if Marlin eventually replaced Ductus as the default JDK rasterizer, but JDK9 is more than a year away AFAIK.

As a short-term solution would it be possible to call the Marlin routines from a custom renderer framework, and leave the sun.java2d.renderer intact? I mean, use Marlin to render map features onto BufferedImages (via the custom framework, not java.awt.Graphics), and use Ductus for everything else.

Laurent Bourgès

unread,
Mar 30, 2015, 5:58:20 AM3/30/15
to marlin-...@googlegroups.com
Hi,


Thanks for the reply. It would be really great if Marlin eventually replaced Ductus as the default JDK rasterizer, but JDK9 is more than a year away AFAIK.

I hope too and I submitted recently several patches to OpenJDK9 to provide marlin back !
 
As a short-term solution would it be possible to call the Marlin routines from a custom renderer framework, and leave the sun.java2d.renderer intact? I mean, use Marlin to render map features onto BufferedImages (via the custom framework, not java.awt.Graphics), and use Ductus for everything else.

Marlin is only a custom java2d renderer for now.

I know that https://code.google.com/p/pisces-graphics/ is a standalone renderer (based on GAE) but it may be slower than marlin which is derived from OpenJDK's pisces but optimized for performance and concurrency.

To satisfy your requirements, someone should develop (or reuse) a java2d alternative (drawing primitives, image processing & filling). Then the Marlin renderer could be refactored to use this new API.

However, it is a big job that I can not do myself and on my own.
If anybody is volunteer to do it, please start that work and I could later help you to refactor Marlin ...


Could you have a look to the pisces-graphics project if it fills your requirements ?
If yes, I could study if it is possible to replace its pisces implementation by a new marlin release adapter to this API.


Would you have some fundings to support such big work ?


Does anybody else have such needs ?

Regards,
Laurent Bourgès

Laurent Bourgès

unread,
Mar 31, 2015, 4:15:42 AM3/31/15
to marlin-...@googlegroups.com

Hi again,

After more reflexion, I think I have an intermediate solution: create a new class  MarlinGraphics2d extends Graphics2d that use best of both aspects:
- use default java2d renderer for font and image rendering
- redirect to marlin for shape and primitive rendering (including blending) using an adapter...

I think it is smart and allowed by java security (and javaws) and less work than reinventing the wheel...

What do you think?

Laurent

Botond Kósa

unread,
Apr 1, 2015, 8:35:18 AM4/1/15
to marlin-...@googlegroups.com
Hi Laurent,

That sounds really promising. It could allow us to use Marlin for map rendering, regardless of whether Marlin would eventually be part of Oracle JDK or not. (OpenJDK is not an option for us, unfortunately.)

Regards,
Botond

Laurent Bourgès

unread,
Apr 1, 2015, 9:28:42 AM4/1/15
to marlin-...@googlegroups.com
Hi Botond,

As usual, the idea seems simple, but in practice it will still be a funny challenge to do it : marlin integration + custom blending (tight integration with Paint, Composite and Clip) !

As I am busy for some time, I keep that topic in mind.

If you or anybody could help (or have fundings), it would be great !

Laurent

Botond Kósa

unread,
Apr 10, 2015, 10:23:34 AM4/10/15
to marlin-...@googlegroups.com
Hi Laurent,

I would happily help in coding and testing the solution. When you have time for it, let me know.

Regards,
Botond

Laurent Bourgès

unread,
Apr 11, 2015, 4:18:28 AM4/11/15
to marlin-...@googlegroups.com, Andrea Aime

Hi Botond,

I think I can soon implement a draft MarlinGraphics2d (rgba image) to design the solution but let it partially implemented; then you could help to support custom Paint, Composite, Stroke, clipping in that new rendering engine...

I propose to create a new github repository (GPL or BSD license) to grant you and andrea contributor rights.

> I would happily help in coding and testing the solution. When you have time for it, let me know.

Thanks for your offer, could you first describe your use case ? What java2d / drawing features do you use in practice ? Let's implement that feature subset first.

Andrea, do you have implemented a custom blender in geoserver handling all porter-duff rules or did you use the java2d AlphaComposite impl ?

Could you help in this new project ?

Cheers,
Laurent

Andrea Aime

unread,
Apr 11, 2015, 8:24:28 AM4/11/15
to Laurent Bourgès, marlin-...@googlegroups.com
On Sat, Apr 11, 2015 at 10:18 AM, Laurent Bourgès <bourges...@gmail.com> wrote:

Andrea, do you have implemented a custom blender in geoserver handling all porter-duff rules or did you use the java2d AlphaComposite impl ?

 

Could you help in this new project ?


Nope, I'm actually reducing my involvement in GeoServer a bit because family has become more time demanding

Cheers
Andrea

Botond Kósa

unread,
Apr 14, 2015, 3:53:36 PM4/14/15
to marlin-...@googlegroups.com, andre...@gmail.com

Thanks for your offer, could you first describe your use case ? What java2d / drawing features do you use in practice ? Let's implement that feature subset first.

We mainly use Graphics2D.draw(Shape s) and Graphics2D.fill(Shape s) with different Shape implementations for polylines and polygons. Before drawing or filling we call setPaint with some simple color, and before drawing also setStroke with some BasicStroke. This is pretty standard drawing code, I guess.

Laurent Bourgès

unread,
May 2, 2015, 12:05:01 PM5/2/15
to marlin-...@googlegroups.com, Andrea Aime

Hi Botond,

I started implementing the MarlinGraphics2d in a new marlin-graphics project.
It seems working: I only redirected all shape operations to the AAShapepipe and GeneralCompositePipe (2 classes cloned from java2d pipeline) so it is quite generic as it reuse many SunGraphics2d features.

PS: I also included my custom BlendComposite that performs proper gamma correction and it looks better ! It is very limited for now but promising.

I will push that on github soon to let you try it in your application (jnlp).

Regards,
Laurent

Le 14 avr. 2015 21:53, "Botond Kósa" <boton...@idata.hu> a écrit :

Thanks for your offer, could you first describe your use case ? What java2d / drawing features do you use in practice ? Let's implement that feature subset first.

We mainly use Graphics2D.draw(Shape s) and Graphics2D.fill(Shape s) with different Shape implementations for polylines and polygons. Before drawing or filling we call setPaint with some simple color, and before drawing also setStroke with some BasicStroke. This is pretty standard drawing code, I guess.

--
You received this message because you are subscribed to the Google Groups "marlin-renderer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to marlin-render...@googlegroups.com.
To post to this group, send email to marlin-...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Laurent Bourgès

unread,
May 4, 2015, 6:26:34 PM5/4/15
to marlin-...@googlegroups.com, boton...@idata.hu, Andrea Aime
Hi Botond,

Here is the first beta release of the Marlin-Graphics project:
https://github.com/bourgesl/marlin-graphics/releases

Marlin-Graphics provides an alternate Graphics2D implementation to redirect shape draw/fill operations to Marlin-renderer instead of Ductus/Pisces renderers (Oracle JDK / OpenJDK).

Usage:

final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

// Create the MarlinGraphics2D wrapping your image's Graphics2D implementation:
final MarlinGraphics2D g2d = new MarlinGraphics2D(image);

// Use g2d to perform java2d operations (draw, fill) as usual

// Do not forget to dispose the graphics2D instance:
g2d.dispose();

Of course, you need to put both jar files in your classpath (no more in the bootclasspath :
  • marlin-graphics-0.1.jar (MarlinGraphics2D) depending on marlin-renderer 0.5.7 (only):
  • marlin-0.5.7-Unsafe.jar (RenderingEngine only)
Enjoy & give me your feedback,
Laurent

Laurent Bourgès

unread,
May 10, 2015, 4:10:09 PM5/10/15
to marlin-...@googlegroups.com, Botond Kósa, Andrea Aime
Dear Botond & Marlin users,

Here is the first public release of the Marlin-Graphics project (v0.2):
https://github.com/bourgesl/marlin-graphics/releases/tag/v0.2.0

Changes:

  • improved integration with java2d pipeline to achieve very good performance (equivalent to marlin replacing JDK's rasterizer)

Usage

// Use Premultiplied RGBA images (TYPE_INT_ARGB_PRE) for performance (15% faster than standard RGBA images (TYPE_INT_ARGB):
final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);

// Create the MarlinGraphics2D wrapping your image's Graphics2D implementation:
final MarlinGraphics2D g2d = new MarlinGraphics2D(image);

// Use g2d to perform java2d operations (draw, fill) as usual
//g2d.setColor(...);
//g2d.setComposite(...);
//g2d.draw(shape);
//g2d.fill(shape);

// Do not forget to dispose the graphics2D instance:
g2d.dispose();

Marlin-Graphics does not require any bootclasspath change:
Just add marlin-graphics and marlin-renderer jar files into your classpath to use it in your application !


Please give me your feedback if you enjoy marlin !

Laurent Bourgès

Botond Kósa

unread,
May 12, 2015, 7:58:10 AM5/12/15
to marlin-...@googlegroups.com, boton...@idata.hu, andre...@gmail.com
Hi Laurent,

Thanks for the quick solution. I will give it a look tonight and provide feedback shortly.

Regards,
Botond

Botond Kósa

unread,
May 12, 2015, 12:00:54 PM5/12/15
to marlin-...@googlegroups.com, boton...@idata.hu
Here is some quick feedback and a few thoughts after my first use of Marlin-Graphics:
  • It works when run from JWS :)
  • Performance seem identical to the original Marlin renderer
  • In MarlinGraphics2D.java the KEY_STROKE_CONTROL rendering hint is set to VALUE_STROKE_NORMALIZE by default, resulting in choppy curves since all shape coordinates are rounded to integer values. This can be overridden from the application, but it would be better to use VALUE_STROKE_PURE by default. I wonder if it would cause any performance impact.
  • We would use Marlin to render on opaque TYPE_INT_RGB images. Could the rendering be optimized to omit the alpha calculations in this case?
Regards,
Botond Kósa

Botond Kósa

unread,
May 12, 2015, 5:31:53 PM5/12/15
to marlin-...@googlegroups.com
Hi Laurent,

After taking a closer look at the Marlin-Graphics implementation and the way we are using Graphics objects, here are some new ideas regarding MarlinGraphics2D instantiation:
  • A constructor with a Graphics2D parameter would be useful. The original BufferedImage is not always available on deeper layers of rendering, only its Graphics object is passed.
  • The create() method now simply forwards to the delegate. It would be useful if it returned a MarlinGraphics2D, not a generic Graphics2D. We often copy the graphics object in rendering methods to preserve its settings (clip, paint, composite etc.) and alter the settings on the copy.
Botond

Laurent Bourgès

unread,
May 13, 2015, 11:27:21 AM5/13/15
to marlin-...@googlegroups.com

Hi Botond,

Thanks for your precious feedback.

I am happy marlin-graphics works well in JavaWebStart (JNLP) and I will asap make your suggested changes...

Few comments below:

> After taking a closer look at the Marlin-Graphics implementation and the way we are using Graphics objects, here are some new ideas regarding MarlinGraphics2D instantiation:
> A constructor with a Graphics2D parameter would be useful. The original BufferedImage is not always available on deeper layers of rendering, only its Graphics object is passed.

Will do but the given Graphics2d must be a SunGraphics2d or MarlinGraphics2d instance...

> The create() method now simply forwards to the delegate. It would be useful if it returned a MarlinGraphics2D, not a generic Graphics2D. We often copy the graphics object in rendering methods to preserve its settings (clip, paint, composite etc.) and alter the settings on the copy.

Agreed. I will clone both g2d...

>> Here is some quick feedback and a few thoughts after my first use of Marlin-Graphics:
>> It works when run from JWS :)

Yahoo!

>> Performance seem identical to the original Marlin renderer

Excellent. You confirm my tests.

>> In MarlinGraphics2D.java the KEY_STROKE_CONTROL rendering hint is set to VALUE_STROKE_NORMALIZE by default, resulting in choppy curves since all shape coordinates are rounded to integer values. This can be overridden from the application, but it would be better to use VALUE_STROKE_PURE by default. I wonder if it would cause any performance impact.

Will fix.

>> We would use Marlin to render on opaque TYPE_INT_RGB images. Could the rendering be optimized to omit the alpha calculations in this case?

Yes, you can any image format you want but RGBA_PRE seems faster on my machine.

Regards,
Laurent

Laurent Bourgès

unread,
May 13, 2015, 5:15:30 PM5/13/15
to marlin-...@googlegroups.com, Botond Kósa
Botond,

I pushed a new minor Marlin-Graphics release (0.2.1):
https://github.com/bourgesl/marlin-graphics/releases

Changes:
  • added constructor MarlinGraphics2D(Graphics2D) which clones the given SunGraphics2D
  • added method setDefaultRenderingHints()
  • fixed create() implementation to clone the MarlinGraphics2D instance
  • use lazy instanciation for shared shape instances

PS: I did not change the KEY_STROKE_CONTROL rendering hint to PURE (left as DEFAULT) as it altered MapBench's outputs...

Laurent

Botond Kósa

unread,
May 14, 2015, 7:13:19 AM5/14/15
to marlin-...@googlegroups.com, boton...@idata.hu
Laurent, I have found a bug in marlin. The drawPolyline method constructs a Polygon from the passed coordinate arrays, and draws that polygon, connecting the last point with the first.

Botond

Laurent Bourgès

unread,
May 14, 2015, 8:12:26 AM5/14/15
to marlin-...@googlegroups.com, Botond Kósa

Botond,

Thanks for the bug report: I will fix it soon.

FYI I only use draw/fill (shape) with one reused GeneralPath(Path2d.Float) in my map rendering code as Graphics primitives are all integer based.

Moreover, I did not have time to write any unit test for all Graphics2d methods.

PS: do you have a github account ? If yes, I could add you as contributor to the marlin-graphics repository if you want.

Cheers,
Laurent

Laurent Bourgès

unread,
May 24, 2015, 12:50:28 PM5/24/15
to marlin-...@googlegroups.com, Botond Kósa

Botond,

Is it a critical bug in your application ?

If so I will fix it asap.

Could you write a simple Graphics2d regression test ?

Please answer,
Laurent

Botond Kósa

unread,
May 26, 2015, 9:02:54 AM5/26/15
to marlin-...@googlegroups.com, boton...@idata.hu
No, it was just some legacy code. Since then we converted all integer-based graphics primitives to shapes, and they are now drawn correctly.

There is however a major obstacle preventing us from using Marlin: licensing. The GPLv2 licence is a consequence of Marlin being a Pisces fork, I presume. Since we have not (yet) opened the source code of our application, we cannot use GPL-licenced libraries in the live environment. Anyway, I will happily test Marlin and provide feedback for you. I do not currently have a GitHub account, but I will create one and then I will also be able to contribute in the code.

Do you have any news about Marlin becoming part of Oracle JDK9? I know than OpenJDK 9 will include Marlin but we cannot force our customers to use OpenJDK instead of Oracle JDK.

Regards,
Botond

Laurent Bourgès

unread,
May 26, 2015, 1:16:09 PM5/26/15
to marlin-...@googlegroups.com, Botond Kósa

Botond,

> No, it was just some legacy code. Since then we converted all integer-based graphics primitives to shapes, and they are now drawn correctly.

Ok I have more time to fix it.

> There is however a major obstacle preventing us from using Marlin: licensing. The GPLv2 licence is a consequence of Marlin being a Pisces fork, I presume. Since we have not (yet) opened the source code of our application, we cannot use GPL-licenced libraries in the live environment. Anyway, I will happily test Marlin and provide feedback for you. I do not currently have a GitHub account, but I will create one and then I will also be able to contribute in the code.

You're right: Marlin is GPL v2 with classpath exception as it is a fork of OpenJDK pisces renderer.

However, the classpath exception restricts the scope of the GPL like LGPL:
http://www.gnu.org/software/classpath/license.html

"
Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination.

    As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.

As such, it can be used to run, create and distribute a large class of applications and applets. When GNU Classpath is used unmodified as the core class library for a virtual machine, compiler for the java languge, or for a program written in the java programming language it does not affect the licensing for distributing those programs directly.
"

So if I understand it correctly, using marlin (gpl + classpath exception), "it does not affect the licensing for distributing those programs directly."

But I am not a lawyer, so you should check what it implies to your application licensing terms.
Please tell me how you interpret such exception.

> Do you have any news about Marlin becoming part of Oracle JDK9? I know than OpenJDK 9 will include Marlin but we cannot force our customers to use OpenJDK instead of Oracle JDK.

For now, the Software Quality team is testing OpenJDK 9 + Marlin (graphics rasterizer branch).

When it will be merged into OpenJDK code base (trunk), I think it will be available in Oracle JDK as pisces does already.
So I can say it is in progress, but without any precise schedule !

Regards,
Laurent

Reply all
Reply to author
Forward
0 new messages