Hi Mario,<br><br>Thanks for the summary of issues.<br><br><blockquote style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote">
So the full payoff only comes if the main application is ignorant of Java,<br>
and communicates only via sockets (or something).<br></blockquote><br>Many of the reasons you cite are very similar to what the ITK (<a href="http://itk.org/">http://itk.org/</a>) developers listed regarding the Bio-Formats ITK plugin (<a href="http://www.loci.wisc.edu/bio-formats/itk">http://www.loci.wisc.edu/bio-formats/itk</a>). Essentially, compiling bf-cpp cross-platform is a substantial burden, and produces an unnecessarily large library with many compile-time dependencies (Java and Boost in particular).<br>

<br>Nonetheless, using Ice instead, while powerful, is not the simplest solution. Though Ice is cross-platform, it constitutes another library dependency and complexifies the build process. What we decided to do instead for the ITK plugin is to use pipes, which address all the issues you listed, and are surprisingly efficient (slightly faster than JNI, in our tests). We actually wrote functional implementations of the Bio-Formats ITK plugin with three different approaches:<br>

<br>  1. Jace -- using bf-cpp as you know it<br>  2. raw JNI -- using JNI directly without Jace<br>  3. pipes -- using system calls to invoke Java and pass data<br><br>For code, see:<br>  <a href="http://git.openmicroscopy.org/?p=bioformats.git;a=tree;f=components/native;hb=HEAD">http://git.openmicroscopy.org/?p=bioformats.git;a=tree;f=components/native;hb=HEAD</a><br>

<br>We found that #3 was much easier to compile cross-platform (no dependencies) and also faster than #2.<br><br>Once we have Bio-Formats Ice bindings again, it would be interesting to implement the Bio-Formats ITK plugin using them as well, to compare performance with the others.<br>

<br>For XuvTools, you might consider using a similar approach, rather than waiting for an Ice-based solution that would still be more complex to compile than the pipes approach. (One major advantage of Ice is that it can be run client/server on different machines, but that doesn&#39;t seem necessary for XuvTools.)<br>

<br><blockquote style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote">Thanks Curtis for this awesome first test, I will try to compile it cross-<br>
platform and see how that works for me! I&#39;ll let you know how it goes, and<br>
possibly we can compare some runtimes of ICE versus Jace/JNI.<br></blockquote>
<br>No problem. If you do end up playing with the code, one thing I realized is that the entry point into the Ice server should not be an IFormatReader instance. It should probably be a utility class &quot;Main&quot; or something that provides all the constructors for the various objects. As such, it would provide hooks into the entire Bio-Formats Java API (or a specific subset, to limit the size and complexity of the resultant library).<br>

<br>Based on our discussions, I filed a few tickets relating to the Bio-Formats C++ and Ice bindings, and related tasks:<br><br>  <a href="http://dev.imagejdev.org/trac/imagej/ticket/653">http://dev.imagejdev.org/trac/imagej/ticket/653</a><br>

  <a href="http://dev.imagejdev.org/trac/imagej/ticket/654">http://dev.imagejdev.org/trac/imagej/ticket/654</a><br>  <a href="http://dev.imagejdev.org/trac/imagej/ticket/655">http://dev.imagejdev.org/trac/imagej/ticket/655</a><br>


  <a href="http://dev.imagejdev.org/trac/imagej/ticket/656">http://dev.imagejdev.org/trac/imagej/ticket/656</a><br>
  <a href="http://dev.imagejdev.org/trac/imagej/ticket/657">http://dev.imagejdev.org/trac/imagej/ticket/657</a><br>
  <a href="http://dev.imagejdev.org/trac/imagej/ticket/658">http://dev.imagejdev.org/trac/imagej/ticket/658</a><br>
  <a href="http://dev.imagejdev.org/trac/imagej/ticket/659">http://dev.imagejdev.org/trac/imagej/ticket/659</a><br><br>If any of these are of interest, let me know and I can add you to the CC list.<br><br>Unfortunately, I am swamped with ImageJ2 tasks, and will probably not have time to work on the Bio-Formats Ice bindings further for a few months, as much as I wish I could.<br>

<br>Regards,<br>Curtis<br><br><div class="gmail_quote">On Fri, Jul 1, 2011 at 7:15 AM, Mario Emmenlauer <span dir="ltr">&lt;<a href="mailto:mario@emmenlauer.de">mario@emmenlauer.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<br>
Hi,<br>
<br>
sorry for my late reply, I was on holidays for a while :-)<br>
Thanks Curtis for the quick followup! Below my comments:<br>
<div class="im"><br>
On 06/30/2011 10:38 PM, Curtis Rueden wrote:<br>
&gt; Hi Josh,<br>
&gt;<br>
&gt;     Was your and Mario&#39;s primary goal to get away from the in-process issues of<br>
&gt;     the JVM? Would it be an option to fork, create the JVM, and then use Ice<br>
&gt;     rather than raw sockets for the communication? In that case would you need<br>
&gt;     all objects? Or does the API that Mario is already using come close to<br>
&gt;     sufficing? What are the other features/requirements that need to be added?<br>
&gt;<br>
&gt;<br>
&gt; I believe the goal was to have an inter-process solution to decouple the JVM a<br>
&gt; bit from the C++ program. However, I admit that I am fuzzy on the specifics of<br>
&gt; why Mario wants an inter-process solution. In his talk, he mentioned one problem<br>
&gt; with allocating memory to the JVM a priori, and how to deal with<br>
&gt; OutOfMemoryError, but I am not clear on why an inter-process solution would<br>
&gt; improve on that situation. Mario, any comments?<br>
<br>
</div>Yes, the main goal is to get away from the in-process issues of the JVM,<br>
especially the memory problem, but in addition one goal is to avoid a library<br>
problem with Java. Here a more detailed description:<br>
(1) Java memory hog: the JVM does not free memory back to the System,<br>
    even when calling the gc() explicitly. Memory becomes available to<br>
    other JVM usage, but not available to the OS (and neither to C++)<br>
    anymore, so its &quot;lost&quot; for the main application.<br>
(2) Insufficient Java memory: When creating the JVM, an appropriate<br>
    upper memory limit has to be set. If later during runtime this turns<br>
    out to be insufficient, the JVM can not be re-created (its a singleton).<br>
    Therefore, the main application needs to exit and re-start for the JVM<br>
    memory to be increased.<br>
(3) Java library path: The application that uses Bio-Formats needs to<br>
    resolve at invocation libjvm.so (jvm.dll on Windows). On Windows,<br>
    this is typically done by setting the PATH for the application in<br>
    the registry. If a system-wide Java is used, this path is unknown.<br>
    Therefore, XuvTools ships its own, private Java (an 1200% increase<br>
    in installer size). If the Bio-Formats would be a separate executable<br>
    started via system() or similar, the library path (to the system-wide<br>
    Java) could be dynamically resolved by the main application before-<br>
    hand.<br>
(4) Increasing modularity: Compiling C++ against Java cross-platform is<br>
    painfull. If C++-Bio-Formats would be a separate executable, developers<br>
    of the main application would not have to care (it could come with a<br>
    separate installer).<br>
<br>
So the full payoff only comes if the main application is ignorant of Java,<br>
and communicates only via sockets (or something). Note that (1) and (2)<br>
together create a chicken-egg-problem of setting a good initial JVM memory<br>
size :-)<br>
<div class="im"><br>
<br>
&gt;     Curtis, I assume your plan is to turn everything into an Ice Prx? e.g. would<br>
&gt;     you have an IRandomAccessPrx? If so, I&#39;m skeptical that this would work as<br>
&gt;     well as you want.<br>
&gt;<br>
&gt;<br>
&gt; Yep, everything would be exposed as proxies. So sure, there would be an<br>
&gt; IRandomAccessPrx, but it&#39;s not like most consumers of the API would actually<br>
&gt; make use of it (since I agree, it would be awful performance-wise). Most people<br>
&gt; would interact with the Java library at a less fine-grained level—e.g., calling<br>
&gt; IFormatReader.openBytes to grab one plane at a time. There is still overhead at<br>
&gt; that level, but much less.<br>
<br>
</div>This would translate 1:1 to my current interface, sounds great! Anyways I<br>
should mention that pixel access with Jace/JNI has horrible performance -<br>
copying one image plane pixel-by-pixel was on the order of several seconds,<br>
whereas memcopy() or GetArrayRegion() take milliseconds. So ICE would likely<br>
not do much worse, at least on localhost :-)<br>
<div><div></div><div class="h5"><br>
<br>
&gt;     I can&#39;t remember the specific problem we were having, Curtis. To you have<br>
&gt;     that email still and/or link on ome-devel? I found only<br>
&gt;     <a href="http://lists.openmicroscopy.org.uk/pipermail/ome-devel/2010-October/001733.html" target="_blank">http://lists.openmicroscopy.org.uk/pipermail/ome-devel/2010-October/001733.html</a><br>
&gt;<br>
&gt;<br>
&gt; I couldn&#39;t find it on the mailing list either; perhaps we discussed it over chat.<br>
&gt;<br>
&gt; To understand the problem again after so long, I mocked up a Slice interface for<br>
&gt; a small subset of the Bio-Formats API. In so doing, I found the solution to the<br>
&gt; previous issue on this page of the Ice manual:<br>
&gt;<br>
&gt;   <a href="http://doc.zeroc.com/display/Ice/Object+Incarnation+in+Java" target="_blank">http://doc.zeroc.com/display/Ice/Object+Incarnation+in+Java</a><br>
&gt;<br>
&gt; To describe briefly, say we have the following Slice definition:<br>
&gt;<br>
&gt;   interface CoreMetadata;<br>
&gt;   interface IMetadata;<br>
&gt;   interface IFormatReader {<br>
&gt;     CoreMetadata* getCoreMetadata();<br>
&gt;     IMetadata* getMetadataStore();<br>
&gt;   };<br>
&gt;<br>
&gt; When implementing servants on the server side, you must implement methods that<br>
&gt; return proxies of other servants; e.g.:<br>
&gt;<br>
&gt;     public CoreMetadataPrx getCoreMetadata(Current current);<br>
&gt;     public IMetadataPrx getMetadataStore(Current current);<br>
&gt;<br>
&gt; I was stumped on how to translate a server-side Java object into a proxy of a<br>
&gt; servant that wraps that object. The solution (from the Ice page linked above) is:<br>
&gt;<br>
&gt;   CoreMetadataPrx proxy = CoreMetadataPrxHelper.uncheckedCast(<br>
&gt;     current.adapter.addWithUUID(new CoreMetadataI(coreMetadata)));<br>
&gt;<br>
&gt; (Assuming that the CoreMetadataI servant implementation has a constructor that<br>
&gt; takes a CoreMetadata object, of course.)<br>
&gt;<br>
&gt; Personally, I would describe that invocation as &quot;horribly unintuitive&quot; and<br>
&gt; perhaps &quot;needlessly complex&quot; (why not &quot;current.adapter.createProxy(new<br>
&gt; CoreMetadataI(coreMetadata))&quot;), but at least there is a way to do it!<br>
&gt;<br>
&gt; I have posted my full solution at:<br>
&gt;<br>
&gt;   <a href="http://dev.loci.wisc.edu/curtis/bf-ice/" target="_blank">http://dev.loci.wisc.edu/curtis/bf-ice/</a><br>
&gt;<br>
&gt; There are shell scripts for launching the server and the client, and a small<br>
&gt; test to verify that information is being communicated properly. All works, so I<br>
&gt; think my proposal to autogenerate a Slice file from a Java JAR file is doable.<br>
&gt; The only question is: when will I find the time?<br>
<br>
</div></div>Thanks Curtis for this awesome first test, I will try to compile it cross-<br>
platform and see how that works for me! I&#39;ll let you know how it goes, and<br>
possibly we can compare some runtimes of ICE versus Jace/JNI.<br>
<br>
All the best,<br>
<font color="#888888"><br>
    Mario<br>
</font><div class="im"><br>
<br>
<br>
&gt;<br>
&gt; Regards,<br>
&gt; Curtis<br>
&gt;<br>
&gt; On Tue, Jun 21, 2011 at 7:12 AM, Josh Moore &lt;<a href="mailto:josh@glencoesoftware.com">josh@glencoesoftware.com</a><br>
</div><div><div></div><div class="h5">&gt; &lt;mailto:<a href="mailto:josh@glencoesoftware.com">josh@glencoesoftware.com</a>&gt;&gt; wrote:<br>
&gt;<br>
&gt;<br>
&gt;     On Jun 17, 2011, at 11:17 AM, Curtis Rueden wrote:<br>
&gt;<br>
&gt;     &gt; Hi everyone,<br>
&gt;<br>
&gt;     Hi,<br>
&gt;<br>
&gt;     &gt; Yesterday Mario Emmenlauer and I discussed the Bio-Formats Ice bindings, and<br>
&gt;     &gt; how it would be nice to resurrect them so that Bio-Formats has an<br>
&gt;     &gt; inter-process, cross-language integration solution.<br>
&gt;     &gt;<br>
&gt;     &gt; I started looking at how best to resurrect them. The way they were being<br>
&gt;     &gt; done before was very ad hoc. We generated them from a Velocity template that<br>
&gt;     &gt; was quite hard-coded in many ways compared to the way the way the C++<br>
&gt;     &gt; bindings work. See:<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     <a href="http://git.openmicroscopy.org/?p=bioformats.git;a=blob;f=components/autogen/src/ice/bio-formats.vm;hb=HEAD" target="_blank">http://git.openmicroscopy.org/?p=bioformats.git;a=blob;f=components/autogen/src/ice/bio-formats.vm;hb=HEAD</a><br>


&gt;     &gt;<br>
&gt;     &gt; In contrast, the C++ bindings wrap every method of every Java class in<br>
&gt;     &gt; bio-formats.jar, loci-common.jar and ome-xml.jar.<br>
&gt;     &gt;<br>
&gt;     &gt; We could do something similar for the Bio-Formats Ice bindings—generate a<br>
&gt;     &gt; Slice file mirroring the Bio-Formats API as fully as possible—but it would<br>
&gt;     &gt; require a bit of work. And of course it results in a very granular remoting<br>
&gt;     &gt; API compared to how people often use Ice. Nonetheless, it would make for an<br>
&gt;     &gt; intuitive API, as long as people exercise some care not to make too many<br>
&gt;     &gt; remote calls as Mario mentioned in his XuvTools talk yesterday.<br>
&gt;     &gt;<br>
&gt;     &gt; Do others agree that such a thing would be useful? If so, I am thinking<br>
&gt;     &gt; about how best to implement it. My initial inclination is to write some Java<br>
&gt;     &gt; code that takes a JAR file as input, and generates a Slice file with<br>
&gt;     &gt; interfaces mirroring each class in the JAR, as well as the Java server<br>
&gt;     &gt; implementation code that simply delegates to the wrapped JAR.<br>
&gt;<br>
&gt;     Was your and Mario&#39;s primary goal to get away from the in-process issues of<br>
&gt;     the JVM? Would it be an option to fork, create the JVM, and then use Ice<br>
&gt;     rather than raw sockets for the communication? In that case would you need<br>
&gt;     all objects? Or does the API that Mario is already using come close to<br>
&gt;     sufficing? What are the other features/requirements that need to be added?<br>
&gt;<br>
&gt;     &gt; My questions, mostly to those who know more about Ice, are:<br>
&gt;     &gt;<br>
&gt;     &gt; 1) Is there already a tool out there for doing this? Or a better way in<br>
&gt;     &gt; general?<br>
&gt;<br>
&gt;     None that I know of.<br>
&gt;<br>
&gt;     &gt; 2) Are there any roadblocks you can foresee with this approach, aside from<br>
&gt;     &gt; bad performance in some cases?<br>
&gt;<br>
&gt;     Curtis, I assume your plan is to turn everything into an Ice Prx? e.g. would<br>
&gt;     you have an IRandomAccessPrx? If so, I&#39;m skeptical that this would work as<br>
&gt;     well as you want.<br>
&gt;<br>
&gt;     &gt; One potential roadblock: years ago I had trouble with methods of one<br>
&gt;     &gt; interface returning objects of a different interface. At the time, Josh<br>
&gt;     &gt; Moore and I concluded that it was sort of infeasible to have these sorts of<br>
&gt;     &gt; methods. E.g., IFormatReader.getCoreMetadata() returns a CoreMetadata<br>
&gt;     &gt; object, but this is difficult to implement properly in the server-side<br>
&gt;     &gt; implementation due to how Ice proxies work. But my intuition is that there<br>
&gt;     &gt; may be a clever workaround...<br>
&gt;<br>
&gt;     I can&#39;t remember the specific problem we were having, Curtis. To you have<br>
&gt;     that email still and/or link on ome-devel? I found only<br>
&gt;     <a href="http://lists.openmicroscopy.org.uk/pipermail/ome-devel/2010-October/001733.html" target="_blank">http://lists.openmicroscopy.org.uk/pipermail/ome-devel/2010-October/001733.html</a><br>
&gt;<br>
&gt;     &gt; Thoughts welcome!<br>
&gt;     &gt; -Curtis<br>
&gt;<br>
&gt;     Cheers,<br>
&gt;     ~Josh<br>
&gt;<br>
&gt;<br>
</div></div></blockquote></div><br>