<div dir="ltr">Hi Christian & everyone,<div><br></div><div><div>> Curtis can expand on this if necessary, but by avoiding one static</div><div>> Context, we allow multiple instances of applications to run in the</div>


<div>> same JVM with differing sets of Services, Plugins, and any other state</div><div>> that could be desired.</div></div><div><br></div><div>Right. There are valid use cases for having multiple Contexts in the same JVM. But I would not suggest proliferating several Context objects within the same instance of the KNIME application, if you can avoid it.</div>


<div><br></div><div>As a rule of thumb: two objects from different Contexts should not interact. There is currently no way to pass objects between Contexts. Each Contextual object has exactly *one* Context associated with it, which cannot be changed once it is set. This is by design. I am open to changing the design, but at the moment, that's how it works. So if you create object Foo using Context F, and then create object Bar using Context B, and then later Foo and Bar need to interact somehow... the behavior will be undefined at best, unstable or explosive at worst. Such interactions do not always check for "context consistency" but that assumption is definitely implicit throughout the codebase right now.</div>


<div><br></div><div>So I agree with Mark: best if you can create one Context that has all the services you need, and you can reuse that Context everywhere. If this is a problem for OSGi-related reasons (e.g., class loaders) then perhaps we can tackle those issues at our next hackathon. :-)</div>


<div><br></div><div>Regards,</div><div>Curtis</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 14, 2014 at 8:39 AM, Mark Hiner <span dir="ltr"><<a href="mailto:hiner@wisc.edu" target="_blank">hiner@wisc.edu</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Christian,<br><div><br></div><div>These are both great questions, so no worries!<br></div><div><br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">




* If I want to use a global "Context" in my complete "KNIME
      Application", why is there the possibility to create several
      contexts?<br></blockquote><div><br></div><div>Curtis can expand on this if necessary, but by avoiding one static Context, we allow multiple instances of applications to run in the same JVM with differing sets of Services, Plugins, and any other state that could be desired. I don't have specific use cases off hand, but fundamentally, avoiding static classes and allowing state to be encapsulated with each instance of a Context is considerably more flexible. I think the only advantage a static Context would have is that it might mitigate some confusion. ;)<br>




<br></div><div>Also, if you know you want a static Context, it's easy enough to create a static utility class with a getContext() method that provides a consistent Context instance for everything in your application.<br>




</div><br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
      * How can I use the class "Scifio" in a global way, s.t. this
      context also knows all other services? The "Scifio" Context class
      itself suggests to create one context for ImageJ2, one for SCIFIO,
      etc.?!<br></blockquote><br></div><div>I'm not sure exactly what you mean when you reference the "Scifio" Context. But note that <a href="https://github.com/scifio/scifio/blob/master/scifio/src/main/java/io/scif/SCIFIO.java#L97" target="_blank">the SCIFIO class</a> has a constructor that accepts an existing Context. The SCIFIO class was designed, fundamentally, to act as a wrapper for existing Contexts. So you can maintain your one application context, and create a new SCIFIO around it when needed. The zero-param constructor is primarily a convenience for when you don't have/need a Context already in your application.<br>




<br></div><div>So to make SCIFIO global, just have a single global Context and then wrap it with a SCIFIO whenever you need the SCIFIO API. There are many ways you could implement this - using a static utility method as above, or adding a HasSCIFIO layer on top of <a href="https://github.com/scijava/scijava-common/blob/master/src/main/java/org/scijava/AbstractContextual.java" target="_blank">AbstractContextual</a> classes (which we actually had at one point and then moved away from), etc...<br>




<br></div><div>Hope this helps. Let me know if anything is unclear.<br><br></div><div>- Mark<br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote"><div>On Tue, Jan 14, 2014 at 4:43 AM, Christian Dietz <span dir="ltr"><<a href="mailto:christian.dietz@uni-konstanz.de" target="_blank">christian.dietz@uni-konstanz.de</a>></span> wrote:<br>




</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF">
    <div>Hi Mark,<br>
      <br>
      maybe a very stupid questions, but I got two more very general
      ones:<br>
      <br>
      * If I want to use a global "Context" in my complete "KNIME
      Application", why is there the possibility to create several
      contexts?<br>
      * How can I use the class "Scifio" in a global way, s.t. this
      context also knows all other services? The "Scifio" Context class
      itself suggests to create one context for ImageJ2, one for SCIFIO,
      etc.?!<br>
      <br>
      Don't misunderstand me, I really want to use the context the way
      you guys think its best, but I understand too little since now I
      guess :)<br>
      <br>
      Have a nice day!<br>
      <br>
      Christian<br>
      <br>
      <br>
      Am 13.01.2014 17:34, schrieb Mark Hiner:<br>
    </div><div><div><div><div>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_extra">Hi Christian,</div>
        <div class="gmail_extra"><br>
          <div class="gmail_quote">On Sat, Jan 11, 2014 at 12:05 PM,
            Christian Dietz <span dir="ltr"><<a href="mailto:christian.dietz@uni-konstanz.de" target="_blank">christian.dietz@uni-konstanz.de</a>></span>
            wrote:<br>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">If so, I thought about
              an "exclude service" option in the Context? Something
              like: Include all SingletonService, but if you include
              them, make sure that they are of type ImageJService or
              SCIFIOService or something like that? Or: The user can
              provide a "ServiceFilter" Implementation where he can
              exclude/Include certain services? I don't know if this
              makes sense at all, just a naive thinking I guess.</blockquote>
            <div><br>
            </div>
            <div>I understand what you're saying, but there are
              significant problems with excluding services like this.
              It's really not extensible - it will always be possible
              for something downstream to add a problematic service.
              Unless you have complete control of the classpath - but if
              you have that, you can limit which services and plugins
              are discovered, and thus loaded, anyway.<br>
              <br>
            </div>
            <div>So let's go more into the philosophy of what you're
              trying to do:<br>
              <br>
            </div>
            <div>- Why severely limit Services available to the Context?
              From what I understood (and please correct me if I'm wrong
              here) you have one class loader and one context per
              plugin? So you want to limit the number of services
              because each plugin is going to load a new context? Is
              that right?<br>
              <br>
            </div>
            <div>If so, I feel like the Context use is a bit too
              narrowly scoped here. It's developed as more of an
              application-level context, so I think it will be a
              continuous struggle to use it as something else. Would it
              be possible to refactor your context usage to simply have
              one Context, that loads all of the services/plugins
              available, and is then passed around/reused by other
              modules?<br>
            </div>
          </div>
        </div>
        <br>
        <div> Thanks,<br>
          Mark<br>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <br>
        <div class="gmail_quote">On Sat, Jan 11, 2014 at 12:05 PM,
          Christian Dietz <span dir="ltr"><<a href="mailto:christian.dietz@uni-konstanz.de" target="_blank">christian.dietz@uni-konstanz.de</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div text="#000000" bgcolor="#FFFFFF">
              <div>Hi Mark,<br>
                <br>
                I figured out my problem and I have no clue how to solve
                it in a nice way :-)<br>
                <br>
                We restrict our the context we create to very limited
                amount of services. We only want to load the services we
                really need. <br>
                Since now, I told my Context to load all
                SingletonService.class. I needed to load all
                SingletonServices, such that the method
                isMultipleChoiceObject (line 382) returns "true" for
                e.g. the "CalculatorOp" and KNIME can generate the
                dialog for e.g. the ImageCalculator. This only worked if
                the CalculatorService.class is available in the context.<br>
                <br>
                The important part actually is: If I request to load
                _any_ SingletonService, of course also the
                SingletonServices from SCIFIO etc are also loaded, which
                I actually don't need here. On the other hand, I don't
                want to manually add SingletonServices from ImageJ2 I
                need (this is what I do now with CalculatorSerice,
                ThresholdService, etc... see line 128/129 at
                <a href="https://github.com/knime-ip/knip-imagej2/blob/master/org.knime.knip.imagej2.core/src/org/knime/knip/imagej2/core/IJGateway.java" target="_blank">https://github.com/knime-ip/knip-imagej2/blob/master/org.knime.knip.imagej2.core/src/org/knime/knip/imagej2/core/IJGateway.java</a>).<br>





                <br>
                Does this make sense?<br>
                <br>
                If so, I thought about an "exclude service" option in
                the Context? Something like: Include all
                SingletonService, but if you include them, make sure
                that they are of type ImageJService or SCIFIOService or
                something like that? Or: The user can provide a
                "ServiceFilter" Implementation where he can
                exclude/Include certain services? I don't know if this
                makes sense at all, just a naive thinking I guess.<br>
                <br>
                Thanks for your support again,<br>
                <br>
                Christian
                <div><br>
                  <br>
                  <br>
                  Am 10.01.2014 19:57, schrieb Mark Hiner:<br>
                </div>
              </div>
              <blockquote type="cite">
                <div dir="ltr">
                  <div>
                    <div>
                      <div>
                        <div>
                          <div>OK, so I'm questioning how the <a href="https://github.com/knime-ip/knip-imagej2/blob/master/org.knime.knip.imagej2.core/src/org/knime/knip/imagej2/core/IJGateway.java#L428" target="_blank">IJAdapterProvider</a>
                            assembles the list of services..
                            <div>
                              <div><br>
                                <br>
                                It seems like it's trying to manually
                                assemble a list of services to construct
                                the context with. Is that right? When
                                constructing the context and providing a
                                list of services, you basically can give
                                it just the superclass services, and all
                                children will be discovered. We did that
                                so you can make a context with say
                                SCIFOService and SciJavaService and then
                                plugins that add more SCIFIOServices
                                will automatically be included.<br>
                                <br>
                                Does that make sense?<br>
                                <br>
                              </div>
                            </div>
                          </div>
                          <div>
                            <div> So I would possibly
                              refactor this to make a context with
                              ImageJServices, SCIFIOServices, and
                              SciJavaServices.. because those are the
                              relevant components you're using, right?<br>
                              <br>
                            </div>
                          </div>
                        </div>
                        <div>
                          <div> Also, yes whenever you try to
                            get objects from an ObjectIndex, ALL pending
                            initializations occur. This just defers the
                            initialization until it's required.<br>
                            <br>
                          </div>
                        </div>
                      </div>
                      <div>
                        <div> All SingletonServices add each
                          of their singleton instances to the
                          ObjectIndex lazily during their initialize()
                          method. So that's why these translators are
                          being loaded. And they fail because
                          SCIFIOServices aren't included.<br>
                          <br>
                          So, context creation is part of the problem..
                          but I think the classpath/class loader is
                          still incorrect, because you have OME-Formats
                          stuff in it.<br>
                          <br>
                          I will try to update the Context so that when
                          that error comes up, it prints out the
                          services that WERE used to create the context,
                          and maybe the classpath of the current class
                          loader. Because that error is extremely
                          cryptic and unhelpful.<br>
                          <br>
                          Then maybe we can discuss more tomorrow!<br>
                          <br>
                        </div>
                      </div>
                    </div>
                    Take care<br>
                  </div>
                  Mark<br>
                </div>
              </blockquote>
              <br>
            </div>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </div></div></div></div></div>

</blockquote></div><br></div><div><div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups "scijava" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:scijava%2Bunsubscribe@googlegroups.com" target="_blank">scijava+unsubscribe@googlegroups.com</a>.<br>
For more options, visit <a href="https://groups.google.com/groups/opt_out" target="_blank">https://groups.google.com/groups/opt_out</a>.<br>
</div></div></blockquote></div><br></div></div>