tag:blogger.com,1999:blog-19686318824694642622024-03-20T11:07:56.569-04:00Eclipse Ruminationsruminate (v). 1. To turn a matter over and over in the mind. 2. To chew cud.
<br><br>
The views displayed here are my own, and do not represent those of my employer.Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.comBlogger14125tag:blogger.com,1999:blog-1968631882469464262.post-87160824306292830792010-12-21T15:42:00.001-05:002010-12-21T15:43:18.828-05:00Eclipse to Visual Studio 2010: What I'm MissingI've recently been spending a lot of my time in Visual Studio 2010. Having been in Eclipse for many years, the transition has been somewhat painful. In no particular order, here are the features that I'm still trying to track down. VS experts, help me out!<br />
<br />
<ol><li>Quick Fix - Assign to local variable. Write the RHS of an assignment statement, then Ctrl+1 to have the IDE suggest/insert a LHS.</li>
<li>Curly brace auto-completion. When I type the opening brace and hit enter, automatically indent one tab and add a close brace on the following line.</li>
<li>Ctrl-Click for type definition hyperlinking. Basically, a mouse gesture for Visual Studio's Go To Definition F12. I've been told there is an extension for this??</li>
<li>Ctrl-Click for externalized strings (resources in .NET?). In Eclipse, when I Ctrl-Click on an externalized message referenced as a static String, I can jump to the properties file directly.</li>
<li>"Flexible" Go To Definition. In Eclipse, if I write some code that calls a method, and I don't have the particular overload parameters sequenced correctly, I can still (typically) jump to the definition of one of the overloads. Since they're typically clustered together in the target type, this is a poor man's way of getting around reading the Javadoc.</li>
<li>(Speaking of Javadoc), Hover over a method to see its NDoc documentation. Reading the commented XML syntax on a method doesn't do it for me.</li>
<li>Link With Editor / Show In. When I'm jumping around using Go To Definition, I quickly lose track of where (in the resource tree) a particular class is. In Eclipse, I can toggle and untoggle Link With Editor to highlight the resource in Package Explorer. How do I select the current editor's file in Solution Explorer?</li>
<li>Synchronize View. This one is a HUGE hole. How the hell do you .NET people sync your code in a sane way??</li>
<li>Multi-Page Editors. I'll qualify this one a bit by saying that I've seen the implementation details of multi-page editors in Eclipse, and there are some definite issues. But the functionality is critical when you have an XML document which also has a graphical editor. (Entity Framework conceptual models, I'm lookin' at you.) Gimme a synchronized two-tab editor so I don't have to keep doing Open With, closing the other editor (can't have both open at the same time, another FAIL), etc.</li>
<li>Outline View in the XML editor. 'Nuff said.</li>
<li>Collapse All / Expand All. Solution Explorer needs these badly.</li>
<li>File -> Restart. After I install a Visual Studio Extension, I need to restart. Please make this one click, thanks. </li>
<li>Workspaces. I really don't know how to explain this one. You can see one of my complaints (relating to Team Explorer) in <a href="http://stackoverflow.com/questions/3806612/how-to-specify-visual-studio-team-explorer-collection-on-start-up">this post</a>. Another example is that of "recent solutions". Please just keep my last solution open? What am I missing here? I need to have separate "threads" of work that are preserved somehow, so I can easily switch between conceptual projects in my daily work.</li>
</ol><br />
Please post back in the comments with answers to all of these so that I don't resort to editing C# code in Eclipse. Thanks.Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com12tag:blogger.com,1999:blog-1968631882469464262.post-51746595505502173522010-11-11T12:13:00.001-05:002010-11-11T12:14:52.289-05:00Testing declarative Eclipse expressionsOur Eclipse-based product plugs into the platform debug support. And we have a large number of launch shortcuts which have enablement expressions specified in plugin.xml. And they are a huge pain in the ass to test manually. If a particular shortcut is disabled when it should be enabled, there isn't a good way (that I've seen) to trace the evaluation of the enablement expression at runtime. So it comes down to stepping through the deeply nested Expression.evaluate(..) calls, and you can easily get lost.<br />
<br />
This is one of those times where I feel like the light bulb should have gone on for me years ago. It turns out there is a much easier way to test these things: by writing JUnit Plug-in Tests for them.<br />
<br />
What follows is some sample code to do this. Since I'm testing the enablement of launch shortcuts, the configuration elements are specific to that scenario, but you should be able to do this for any expression that appears in a bundle's plugin.xml.<br />
<br />
In a @Before method, I read the expression from the plugin.xml and convert it into an Expression object.<br />
<br />
<pre class="brush: java">IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.EXTENSION_POINT_LAUNCH_SHORTCUTS);
IConfigurationElement[] infos = extensionPoint.getConfigurationElements();
for (IConfigurationElement elem : infos) {
String id = elem.getAttribute("id");
IConfigurationElement contextLaunch = null;
IConfigurationElement enablement = null;
if ("myShortcutId".equals(id)) {
contextLaunch = elem.getChildren("contextualLaunch")[0];
enablement = contextLaunch.getChildren("enablement")[0];
expression = ExpressionConverter.getDefault().perform(enablement);
}
</pre><br />
<br />
And in a @Test method, I set up the context I'm trying to mimic and evaluate the expression.<br />
<br />
<pre class="brush: java">@Test
public void ui() throws Exception {
List<object> ctxt = new ArrayList<object>();
ctxt.add(selectedObject /*Some IResource, perhaps*/);
IEvaluationContext context = new EvaluationContext(null, ctxt);
context.addVariable("selection", ctxt); //$NON-NLS-1$
assertEquals(EvaluationResult.valueOf(m_uiEnabled), expression.evaluate(context));
}
</pre><br />
Now I can muck around in those delicately constructed XML expressions and rest assured that I have a test suite watching my back.Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com4tag:blogger.com,1999:blog-1968631882469464262.post-7883174495209064912010-02-01T12:37:00.014-05:002010-02-01T13:58:04.549-05:00JUnit4 and the Eclipse Test Framework: Success!(If you're eager, just jump down to the bolded part about victory.)<br /><br />First, some background. I think the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.test/testframework.html">Eclipse Test Framework</a> is one of the gems that is part of Eclipse. Effectively it's a way to run JUnit tests against your bundles while Equinox OSGi is running. You can also have the whole workbench UI running if you like, which I think is a common case. In fact, for quite some time, that was the *only* case that I considered it for. If I had a JUnit test that didn't need the workbench, I could "Run As -> Junit Test". If I had a Junit test that needed the workbench, I could "Run As -> Junit Plug-in Test". But I never really mentally equated the "workbench" with "OSGi framework."<br /><br />Then I went to write a test for one of my bundles that has a dependency on Jetty. And its a version of Jetty that is different from the one that ships with Eclipse. When I ran it as a vanilla "Junit Test" from within Eclipse, everything worked fine. I think I just "got lucky" and it picked up the right version of Jetty when I launched the test. But when I ran my test via the Ant "junit" task (no Eclipse Test Framework), it failed because the wrong version of Jetty got loaded. All of a sudden I realized that without my delicately constructed dependencies being managed by OSGi, I was lost back in the world of "which JAR file is getting used?"<br /><br />So, this brings me to the real guts of this blog post. After discovering I needed OSGi during test execution, I took a second look at the Eclipse Test Framework. Wow, this looks promising! Headless OSGi-based bundle testing! Just what I need. So I converted my build script to go that route, only to run smack dab into <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=153429">bug 153429</a>, which captures that the Eclipse Test Framework only supports JUnit3. <br /><br />That was at least a year ago, maybe two. I commented out my Jetty test and continued running my other JUnit4 tests using Ant. I even wrote some JUnit3 tests that I could run against the Eclipse Test Framework. Meanwhile, the CC list on <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=153429">bug 153429</a> <a href="http://downloads.instantiations.com/WindowTesterDoc/integration/latest/docs/html/faq/faq.html#DoesWindowTestersupportJUnit4tests">continued</a> to <a href="http://rcpquickstart.com/2007/08/06/running-automated-tests-with-pde-build/#comment-3595">build</a> and milestones kept passing without any progress. I stubbornly left alone my Jetty test, refusing to rewrite it for Junit3 since I figured Junit4 on ETF was right around the corner.<br /><br /><span style="font-weight:bold;">Finally with Eclipse 3.6M5 we have complete and utter victory.</span> I have successfully executed my Junit4 tests with the Eclipse Test Framework. I'm not building my product against 3.6 yet (still 3.5.0 actually), but I still was able to grab the <a href="http://download.eclipse.org/eclipse/downloads/drops/S-3.6M5-201001291300/download.php?dropFile=eclipse-test-framework-3.6M5.zip">zip for ETF</a> and make it part of my base Eclipse for PDE build to consume. <br /><br />Now that I have my tests working, I do have some observations to share.<br /><br />Rather than launching the SDK to run my tests, I'm launching my own product, spit out by PDE build. Part of the reason is that I have some additional plug-in tests written using <a href="http://www.instantiations.com/windowtester/">WindowTester</a>, and they care that it's my product which is launched, not the SDK.<br /><br />There was a gotcha with this. ETF was created before p2. So you just dropped your test bundles into the "plugins" folder of the SDK, launched the SDK specifying the ETF application and test bundle / test class, and off you go. Today, if you do the same, and you're launching the SDK to run your tests, it will still work because the SDK ships with the dropins reconciler enabled. My product does not (which is the default, I believe). <span style="font-weight:bold;">So I couldn't simply drop in my test bundles and make them available for ETF to find.</span><br /><br />The solution to this is actually quite clean and works nicely. <br /><ol><br /><li>Enclose test bundles in a test feature, expressing the appropriate dependency on ETF. (Hint: I had to edit the feature.xml manually to include it, since I didn't make ETF part of my target, so I couldn't pick it from the PDE editors.)<br /><li>Run PDE build to build the test feature after building the product.<br /><li>Save off a copy of the product before I test with it.<br /><li>Formally install the test feature into the product using the <a href="http://wiki.eclipse.org/Equinox_p2_director_application">p2 director</a>.<br /><li>Launch the product, specifying the ETF application, and a test bundle / test class that has been installed into the product.<br /></ol><br />I've also included in my test feature the <a href="http://www.eclemma.org/research/instrumentingosgi/index.html">EMMA OSGi bundle</a> for measuring the coverage provided by my bundle tests.<br /><br />Thanks to everyone who voted, provided patches, and general community support to get the ETF supporting JUnit4. It really completes the testing package that is available to developers working with Eclipse and more generally OSGi.Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com3tag:blogger.com,1999:blog-1968631882469464262.post-72747908235921263002009-06-30T09:10:00.005-04:002009-06-30T10:06:31.196-04:00p2 UI policy and Declarative ServicesThis is another post in what is becoming a short (so far only two) series about moving a product from 3.4 to 3.5.<br /><br />After I got my <a href="http://eclipse-ruminations.blogspot.com/2009/06/debugging-pde-build-and-publisher.html">build working</a>, the next step was making sure that I could update from one product version to the next. I was especially excited about the resolution of <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=246060">https://bugs.eclipse.org/bugs/show_bug.cgi?id=246060</a> which allows for .qualifier to be replaced in a product version. No longer would I have to manually increment the product version number for purposes of updating to and testing a nightly build.<br /><br />So my plan was:<br /><ol><br /><li>Run PDE product build to generate version 1.0.0.abc<br /><li>Unzip 1.0.0.abc to some location.<br /><li>Run PDE product build again to generate version 1.0.0.def<br /><li>Launch 1.0.0.abc, point it at the repository for 1.0.0.def, and update.<br /><li>...<br /><li>Profit.<br /></ol><br />Unfortunately, when I launched 1.0.0.abc, the Install New Software dialog didn't have a way for me to add a new repository. Ditto for the preference page.<br /><br />Turns out there is a more robust set of p2 UI building blocks in 3.5, which is handy for RCP developers. That is described in great detail here: <a href="http://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Application">http://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Application</a><br /><br />I should mention that the RCP-p2 example in 3.5 is leaps and bounds ahead of the one from 3.4 (there wasn't one) - so props to the p2 UI team on that.<br /><br />At any rate, the wiki page tipped me off that there is a UI policy which controls what components are showing and enabled. This policy is implemented as an <a href="http://www.eclipse.org/equinox/bundles/">OSGi declarative service</a>. What really threw me for a loop is that I wasn't trying to do anything special with this policy. I just wanted the stock SDK one since our product is based on the SDK.<br /><br /><span style="font-weight:bold;">Debugging the Policy Behavior</span><br /><br />I stepped through the preference page code and discovered that the <code>SDKPolicy</code> wasn't getting discovered as a service (it was just getting an empty <code>Policy</code> every time). So this sent me down the route of launching with <code>-console</code> to see the OSGi console and look for the policy service. After fighting with the filter syntax for the <code>services <filter></code> console command, I googled a bit more and found <a href="http://wiki.eclipse.org/Equinox/RuntimeOptions">these useful runtime options</a> for spitting out verbose DS logging information. I turned those on but I didn't get anything logged. I was pretty stumped at this point. <br /><br />Then a light bulb came on: maybe declarative services wasn't running at all? A quick <code>ss ds</code> at the console showed that it was <code>RESOLVED</code> but not active! I did a <code>start</code> to spin it up and all of a sudden a deluge of DS logging information printed out. And then <code>SDKPolicy</code> started working, and voila my p2 UI was working.<br /><br />It turns out the root cause is that we had a custom <code>config.ini</code> in 3.4 to specify a custom <code>osgi.instance.area</code> location. This was screwing up the start level for the ds bundle. I switched the product to generate a <code>config.ini</code> for me, did a new build, and everything worked. I plan to migrate the <code>osgi.instance.area</code> configuration step to a <code>p2.inf</code> file, which is what the platform releng guys do.<br /><br /><span style="font-weight:bold;">Useful Links</span><br /><br />[1] <a href="http://wiki.eclipse.org/Equinox/RuntimeOptions">Equinox Runtime Options</a><br />[2] <a href="http://www.ibm.com/developerworks/opensource/library/os-ecl-osgiconsole/">Explore Eclipse's OSGi Console</a><br />[3] <a href="http://hwellmann.blogspot.com/2009/04/getting-started-with-osgi-declarative.html">Around the world in Java: Getting Started with OSGi Declarative Services</a><br />[4] <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=256361">p2 UI policy bug #1</a><br />[5] <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=269873">p2 UI policy bug #2</a>Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com8tag:blogger.com,1999:blog-1968631882469464262.post-48928081475162697282009-06-29T13:07:00.005-04:002009-06-29T13:41:47.090-04:00Debugging PDE Build and the publisherI posted a <a href="http://www.eclipse.org/newsportal/article.php?id=1856&group=eclipse.platform.pde#1856">problem</a> to the PDE newsgroup last week about unexpected requirements in my product feature. This was in the context of moving a 3.4-based product to 3.5.<br /><br />The general issue was that the <a href="http://wiki.eclipse.org/Equinox_p2_director_application">director</a> wouldn't install my product because of an unsatisfied requirement. It wasn't clear to me where this requirement was even coming from. Somewhere, there was some metadata in my plugins/features that expressed a dependency that had worked fine in 3.4 but failed in 3.5. My theory was that if I could capture when the publisher was generating the requirement, I'd be able to see the source of that requirement and squash it.<br /><br /><span style="font-weight:bold;">Tracing</span><br /><br />First attempt was to turn on <a href="http://wiki.eclipse.org/FAQ_How_do_I_use_the_platform_debug_tracing_facility%3F">tracing</a> for the p2 components. I managed to find the <code>org.eclipse.equinox.internal.p2.core.helpers.Tracing</code> class which listed out the different options. I stuffed those into a .options file:<br /><pre><br />org.eclipse.equinox.p2.core/debug=true<br />#org.eclipse.equinox.p2.core/generator/parsing=true<br />#org.eclipse.equinox.p2.core/engine/installregistry=true<br />#org.eclipse.equinox.p2.core/metadata/parsing=true<br />#org.eclipse.equinox.p2.core/artifacts/mirrors=true<br />#org.eclipse.equinox.p2.core/core/parseproblems=true<br />#org.eclipse.equinox.p2.core/planner/operands=true<br />#org.eclipse.equinox.p2.core/planner/projector=true<br />#org.eclipse.equinox.p2.core/engine/profilepreferences=true<br />org.eclipse.equinox.p2.core/publisher=true<br />#org.eclipse.equinox.p2.core/reconciler=true<br />#org.eclipse.equinox.p2.core/core/removeRepo=true<br />#org.eclipse.equinox.p2.core/updatechecker=true<br /></pre><br />Then the trick was to pass along those options to the <code>AntRunner</code> app which drives PDE build. I added <code>-debug path/to/.options</code> into my arguments to <code>AntRunner</code>. Running the build again I got two things, neither of which were helpful:<br /><ol><br /><li>Passing <code>-debug</code> to the Platform also passes <code>-debug</code> onto Ant, thanks to <code>AntRunner</code>. So my Ant ran in debug mode which really clouded the issue with about 8mb of debug output.<br /><li>The publisher only outputs two trace statements: start and finish. Nothing about what it is publishing. This may be a candidate for enhancement.<br /></ol><br />Based on these results, I reasoned that nobody else must be using this technique to solve their p2 problems. Moving on.<br /><br /><span style="font-weight:bold;">Stepping through the publisher</span><br /><br />Next up: run <code>AntRunner</code> with Java debug enabled so that I could connect remotely and set breakpoints in the publisher actions. I added the appropriate JVM args to enable the Java wire debug protocol. Started the build again, connected up and started setting breakpoints in various publisher actions. <br /><br />Since the rogue requirement was getting added to my product feature IU, I added a conditional breakpoint in <code>FeaturesAction</code> to look for that feature being processed.<br /><br />Then, since the problematic requirement was <code>org.eclipse.core.resources [3.4.0,3.5.0)</code> I added another conditional breakpoint in <code>getVersionRange</code> to watch for incoming feature entries with 3.4.0 as their minimum version. <br /><br />I did finally discover the problem: I had a bunch of old, outdated entries in my product feature's feature.xml, which included references to several different versions of o.e.core.resources. After I ripped those out, I had a successful build and director install.<br /><br /><span style="font-weight:bold;">Conclusions</span><br /><ul><br /><li>Do not pass the debug flag to <code>AntRunner</code> for purposes of debugging platform code unless you are prepared to wade through volumes of output. (I guess this is a feature of AntRunner - <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=5672">https://bugs.eclipse.org/bugs/show_bug.cgi?id=5672</a>)<br /><li>It was not at all apparent to me to debug p2 actions by setting up a "remote" debug session with PDE build running inside of <code>AntRunner</code>. But it was sure as heck helpful once I figured it out.<br /><li>I am actually glad that I ran across this problem, and that p2 is enforcing these types of constraints, because it helped me clean up outdated dependencies in my feature.<br /></ul><br />How are you debugging your p2 builds??Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com5tag:blogger.com,1999:blog-1968631882469464262.post-82988209612197636842009-05-03T17:51:00.004-04:002009-05-03T18:14:27.665-04:00Cloning a profile using p2I heard at the <a href="http://www.eclipsecon.org/2009/sessions?id=777">p2 BOF</a> at EclipseCon that you could use your profile as a p2 repository. This sounded like a cool way to take an Eclipse setup that you've customized and replicate it into a new install. Granted there may be better ways to do this with shared bundle pools and what have you, but lets set that aside for a moment.<br /><br />Since 3.5M7 is <a href="http://download.eclipse.org/eclipse/downloads/drops/S-3.5M7-200904302300/index.php">out</a>, I decided to take a stab at cloning my 3.5M6 setup into 3.5M7. I had installed SVN and <a href="http://www.eclipse.org/datatools/">DTP</a> along the way so I was hoping this would take the pain out of having to go out and re-provision those items from the web. (Of course I should probably upgrade DTP to the M7 version, but again, lets set that aside.)<br /><br />Steps:<br /><br />1. Unpack 3.5M7 into a new directory<br />2. Launch it<br />3. Help -> Install new software...<br />4. Click the Add button to add a site<br />5. Click Local to browse<br />6. Select the .profile directory from previous install. In my case, file:/C:/eclipse3.5M6/p2/org.eclipse.equinox.p2.engine/profileRegistry/SDKProfile.profile/<br />7. Give it a name, hit OK<br />8. You should see all your plugins from that profile. You might need to uncheck "Show only the latest versions" and "Group items by category"<br />9. Check all the plug-ins you want (sadly, I couldn't find an action to mark multiple at a time)<br />10. Finish the wizard and restart the platform<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGyBHr0koPt5ThPoKm9PglNRERXatGniKajAPjeIollpBxjKvFUPOIvbMyp_1SGQp2RBdB1ViY8j5pd-q5EVJKutW9Zc473JpUqfKTdF4bcPbs66GkomqWU5yKjtfH-oLgv_JvZhfm0Ek/s1600-h/profileinstall.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 335px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGyBHr0koPt5ThPoKm9PglNRERXatGniKajAPjeIollpBxjKvFUPOIvbMyp_1SGQp2RBdB1ViY8j5pd-q5EVJKutW9Zc473JpUqfKTdF4bcPbs66GkomqWU5yKjtfH-oLgv_JvZhfm0Ek/s400/profileinstall.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5331722805622971954" /></a><br /><br />And you're done! Awesome. Thanks to Simon Kaegi for <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=238169">implementing this</a>.Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com8tag:blogger.com,1999:blog-1968631882469464262.post-60657360633329258172009-04-20T22:58:00.002-04:002009-04-20T23:26:41.548-04:00Favoring immutabilityA few years ago, when I read <a href="http://www.amazon.com/Effective-Java-Programming-Language-Guide/dp/0201310058/ref=pd_bbs_sr_3?ie=UTF8&s=books&qid=1240284075&sr=8-3">Effective Java</a> for the first time, <a href="http://vision.bc.edu/~dmartin/teaching/cs102/2008s/reading/Bloch/Item13.pdf">Item 13</a> really stuck in my mind: make your objects immutable wherever possible. You can share them freely. You don't have to worry about checking to see if that <code>Person</code> object you created still has a <code>name</code>. You made sure of that when you created it. And while I don't do a lot of concurrency programming, I've seen time and time again how much you get "for free" when you use immutable objects in multi-threaded environments. So that's another benefit.<br /><br />OK, so I read the book, and moved on. Then I start working on a new project. We happened to pick <a href="http://code.google.com/webtoolkit/">GWT</a> as part of the tool stack. During the early stages, a light bulb goes off in my head: hey, I'm writing a bunch of new beans in Java - I should make them immutable! Silver bullet, right? All my problems will go away. So I write a bunch of immutable beans.<br /><br />Then I tried to serialize my immutable objects, and BAM, I hit this RFE: <a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=1054">Serialize final fields</a>. Turns out, its actually kind of hard to take an immutable object, vaporize it into a bunch of bits, and then reassemble those bits back into an immutable object on the other side. So I ended up with a bunch of objects that really, really wanted to be immutable but couldn't. Frustrating. Turns out that a "90% immutable object" just doesn't have the same feel to it.<br /><br />Alright, so lesson learned (so I thought), moved on. Then I started working on a different project. Same type of deal, writing a bunch of new beans, want to make them immutable so I don't have to worry about whether or not that <code>Person</code> has a <code>name</code>. This time I'm working with <a href="https://jax-ws.dev.java.net/">JAX-WS</a>, and again the serialization problem hits me right in the face. Ultimately I end up leaving my immutable beans alone, and writing a bunch of data transfer objects (similar to the immutable ones, but mutable). Then I could send those across and reassemble them into immutable versions on my own. <br /><br />The saga continued when I made my way into <a href="http://wiki.eclipse.org/index.php/JFace_Data_Binding">JFace Data Binding</a>. I had my Person with their name, age, height, weight, etc. I wanted to have a simple data entry form for a new Person. Problem is, with my immutable Person object, I basically have to set all those properties all at once, during construction. Stopped in my tracks again, since for data binding I basically need a <a href="http://java.sun.com/javase/technologies/desktop/javabeans/docs/spec.html">standard Java bean</a> with getters AND setters. Again I find myself writing intermediate objects which ultimately become their immutable counterparts.<br /><br />The last part of the story came today, when I was poking around the <a href="http://wiki.eclipse.org/Equinox_p2_Getting_Started">p2</a> APIs. I was trying to see how the various properties of an <code>IInstallableUnit</code> got set. I find that there are no setters on the interface. Then I stumble across <code>InstallableUnitDescription</code>:<br /><blockquote><code><br />Once created, installable units are immutable. This description class allows a client to build up the state for an installable unit incrementally, and then finally product the resulting immutable unit.</code></blockquote>A-ha! So I'm not the only one doing a bunch of intermediate stuff just to get to that final immutable object (pun intended).<br /><br />So I put these question to you readers: How are you using immutable objects in your application? How about in your Eclipse applications? What lessons have you learned?Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com5tag:blogger.com,1999:blog-1968631882469464262.post-5849674814203321102009-03-27T00:30:00.004-04:002009-03-27T00:58:37.836-04:00Thanks, EclipseCon '09This was my first year at EclipseCon. It was great to put names to faces and mingle with the community.<br /><br />Here are some things that I learned, in no particular order.<br /><ul><br /><li>Choose Import-Package over Require-Bundle (I feel like I am a bit late to the game on that one, but appreciate being let in on <a href="http://www.osgi.org/blog/2008/06/jsr-277-and-import-package.html">the secret</a>)<br /><li>Someone is <a href="http://www.anyware-tech.com/en/st/eclipse_platform/ecr_rcp_application.html">using RCP</a> to monitor nuclear power plants in France.<br /><li>Migrating a <a href="http://www.linkedin.com/">traditional enterprise application</a> to OSGi is a hard problem.<br /><li>I am running out of <a href="http://www.eclipsecon.org/2009/sessions?id=358">excuses</a> not to use modeling tools.<br /><li>I should scrap my homegrown explorer and use <a href="http://wiki.eclipse.org/index.php/Common_Navigator_Framework">Common Navigator</a>.<br /><li>e4 is <s>coming</s> <a href="http://download.eclipse.org/e4/downloads/drops/S-0.9M1-200902061045/index.html">here</a>. Start using it.<br /></ul><br />Aside from the technical learning, I felt the pulse of the community. And the message is this: <span style="font-weight:bold;">contribute</span>. Submit patches. Write bug reports. Participate in newsgroup discussions. Help wanted. I think this is a great message and frankly I'm overwhelmed by the <a href="http://www.eclipse.org/e4/">number</a> <a href="http://www.rssowl.org/dev">of</a> <a href="http://wiki.eclipse.org/Equinox_p2">areas</a> <a href="http://wiki.eclipse.org/index.php/JFace_Data_Binding">that</a> I want to contribute to. I think I need to submit a proposal to the wife to get more free time...<br /><br />I liked the session voting. I wonder how we could make it paperless? Maybe touch your RFID badge to a +1/0/-1 monitor or something..<br /><br />I hope I am able to come again next year.<br /><br />What did you take away this year (aside from a <a href="https://glassfish.dev.java.net/">fish</a>)?Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com6tag:blogger.com,1999:blog-1968631882469464262.post-4561423985457275482009-03-17T08:55:00.004-04:002009-03-17T09:59:34.761-04:00Keyboard shortcuts and accessibility in GEFHere is a handy reference list of keyboard usage with a <code>GraphicalViewer</code>. Zoom in and zoom out actions must be implemented for those key bindings to work. For panning support, use a <code>PanningSelectionTool</code>.<br /><br /><table><br /><br /><tr><br /><td>Navigate left</td><br /><td>Right arrow</td><br /></tr><br /><br /><tr><br /><td>Navigate right</td><br /><td>Right arrow</td><br /></tr><br /><br /><tr><br /><td>Navigate down</td><br /><td>Down arrow</td><br /></tr><br /><br /><tr><br /><td>Navigate up</td><br /><td>Up arrow</td><br /></tr><br /><br /><tr><br /><td>Navigate into a container</td><br /><td>Alt+Down arrow with the container selected</td><br /></tr><br /><br /><tr><br /><td>Navigate out of a container</td><br /><td>Alt+Up arrow</td><br /></tr><br /><br /><br /><tr><br /><td>Cycle through selection handles</td><br /><td>Press the period key with a part selected</td><br /></tr><br /><br /><tr><br /><td>Move a component</td><br /><td><br /><ol><br /><li>Cycle once to the Move handle using the period key<br /><li>Use navigation keys to move<br /><li>Press Enter to accept new location<br /><li>Press Escape to cancel the move<br /></ol><br /></td><br /></tr><br /><br /><br /><tr><br /><td>Resize a component</td><br /><td><br /><ol><br /><li>Cycle to desired resize handle using the period key<br /><li>Use navigation keys to resize<br /><li>Press Enter to accept new size<br /><li>Press Escape to cancel the resize<br /></ol><br /></td><br /></tr><br /><br /><tr><br /><td>Select multiple</td><br /><td><br /><ol><br /><li>Hold down Ctrl<br /><li>Use navigation keys to navigate to additional components<br /><li>Press Space to select additional components<br /></ol><br /></td><br /></tr><br /><br /><br /><tr><br /><td>Select in sequence</td><br /><td>Hold down Shift, use navigation keys to select additional components</td><br /></tr><br /><br /><tr><br /><td>Zoom In</td><br /><td>Ctrl +</td><br /></tr><br /><br /><br /><tr><br /><td>Zoom Out</td><br /><td>Ctrl -</td><br /></tr><br /><br /><tr><br /><td>Select multiple w/ mouse</td><br /><td>Hold down Ctrl and use the mouse to select components</td><br /></tr><br /><br /><tr><br /><td>Pan when zoomed in</td><br /><td>Hold down Spacebar and drag the mouse</td><br /></tr><br /><br /></table>Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com4tag:blogger.com,1999:blog-1968631882469464262.post-75254273352717812122009-03-16T09:49:00.004-04:002009-03-16T10:02:50.474-04:00Favorites from 3.5M6There are some goodies in <a href="http://eclipsesource.com/blogs/2009/03/15/eclipse-35m6-is-out/">3.5M6</a>. Here are a few of my favorites.<br /><ul><li>DataBinding support for the SWT DateTime widget. No doubt this will be useful. <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=169876">[169876]</a></li><li>DataBinding MultiValidator: Add support for dependencies other than those expressed by IObservables. We have run into this roadblock a few times and its good to see it has been lifted. <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235859">[235859]</a></li><li>Copy/paste support for installed software list. Helpful for reporting issues. <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=227220">[227220]</a></li><li>Enable CTRL-mouse navigation for implementing classes. You know when Ctrl-Click takes you to the interface instead of the implementation? Now its smart. This is awesome. <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=44277">[44277]</a></li><li>New tracing API. Recently noticed we need debug level output in our product and this will be useful in implementing such a log. <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=258705">[258705]</a><br /></li></ul>Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com1tag:blogger.com,1999:blog-1968631882469464262.post-91112639278087474582009-03-13T09:35:00.001-04:002009-03-13T09:36:55.686-04:00EclipseCon 2009 in 1 week!<a href="http://www.eclipsecon.org/2009/"><img src="http://www.eclipsecon.org/2009/static/image/100x100_attending.gif" alt="I'm going to EclipseCon 2009" border="0" width="100" height="100" /></a>Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com0tag:blogger.com,1999:blog-1968631882469464262.post-20091392349580316792009-02-23T10:42:00.009-05:002009-02-23T12:01:59.907-05:00p2 likes its 404s straight upSetting up p2 to work with a repository that is behind HTTPS has been quite challenging. First I ran into <a href="http://bugs.sun.com/view_bug.do?bug_id=6771432">this</a> Java bug which was <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=255397">affecting</a> <a href="http://www.eclipse.org/ecf/">ECF</a>, the underlying transport for p2.<br /><br />After moving past that problem, I was getting a lot of "No repository found at.." error messages, even though I knew damn well there was a repository hosted at the URL I was specifying.<br /><br />After digging through the p2 code with the debugger turned on, I found the problem. You can deploy your repository <a href="http://wiki.eclipse.org/Equinox_p2_Metadata_Generator">metadata</a> in two formats, <a href="http://wiki.eclipse.org/Equinox_p2_Repository_Optimization">compressed</a> (JAR) or uncompressed (XML). When the repository manager goes out to a URL to look for the repository contents, it tries to find the JAR version first. If that fails with a 404, then it looks for the XML version.<br /><br />I was deploying the XML version, and the fallback behavior wasn't working. It was pulling in an empty artifacts file, and trying to parse it, which of course failed. Turns out the web server was sending a 302 redirect with a user friendly page explaining that the page had moved. I found this by intentionally hitting a bad URL with <a href="http://www.mozilla.com/en-US/firefox/">Firefox</a>, using <a href="http://getfirebug.com/">Firebug</a> to examine the response headers:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlQved9HqqTiugjCnfuJGLRYG2wompTEdFD6ooPs1l1sThIiw81IT1ysOhj_CVlL2wy_qPFix0FbJJZLZhqOIohr2clo7d3G3B2r4dT6JC21ewpZaG8UWeKwJYonOaNzZbtVRMjchtrFI/s1600-h/firebug.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 61px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlQved9HqqTiugjCnfuJGLRYG2wompTEdFD6ooPs1l1sThIiw81IT1ysOhj_CVlL2wy_qPFix0FbJJZLZhqOIohr2clo7d3G3B2r4dT6JC21ewpZaG8UWeKwJYonOaNzZbtVRMjchtrFI/s400/firebug.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5306037755487939442" /></a><br /><br />You can see that the 404 is coming AFTER the 302, which is too late. ECF was relying on the 404 to cause a <code>FileNotFoundException</code>, which translates into a known failure status in the p2 repository manager code, from which it can recover and try again with a different filename.<br /><br />After tweaking the web server to return a 404 immediately, I was able to refresh the repository in the Software Updates dialog without any errors.Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com5tag:blogger.com,1999:blog-1968631882469464262.post-59728617036674384472009-02-22T22:08:00.004-05:002009-02-22T22:36:21.968-05:00First look at e4I finally had some time to take a look at the first <a href="http://wiki.eclipse.org/E4">e4</a> Milestone. Download and install from <a href="http://wiki.eclipse.org/E4/Install">here</a>. New and Noteworthy <a href="http://download.eclipse.org/e4/downloads/drops/S-0.9M1-200902061045/e4-news-M1.html">here</a>.<br /><br />My main interest is in the declarative UI and CSS components. So I spun up the photo demo per Boris' <a href="http://wiki.eclipse.org/E4/UI/Running_the_photo_demo">instructions</a>. It works and looks about what I would expect for the first milestone. I found the CSS file and tweaked it a bit, restarted, and saw my changes take effect. That was cool. Some thoughts on CSS in Eclipse:<br /><ul><br /><li>Styling RCP apps can be left up to a designer. I wonder what the collaboration challenges will be like.<br /><li>What does this mean for native widgets? Will people go hog wild and make their application so customized that it doesn't look like it fits in anymore? Ditto for plugins. I see a need for a whole host of new <a href="http://wiki.eclipse.org/User_Interface_Guidelines">UI standards</a>..<br /><li>I wonder how well you can <a href="http://wiki.eclipse.org/FAQ_What_is_hot_code_replace%3F">hot replace</a> your CSS tweaks.<br /><li>I haven't looked at <a href="http://tk-ui.sourceforge.net/user-guide/cssengine.html">Tk-UI</a> (the CSS engine) much yet, but I wonder to what extent they support the CSS spec, and how much of that translates meaningfully into SWT constructs. First thing I'd be looking for is a mapping document.<br /></ul><br />Quick spin through the photo demo is complete. Lets look under the covers at the app itself. First class I look at is <code>ExitHandler</code>. Except, its not a handler. Or at least it doesn't extend <code>AbstractHandler</code>.. what's going on here? I can only guess: dependency injection. This will take some getting used to.<br /><br />I also see an .xmi file. Quickly I can scan through it and see the structure of the entire user interface. I'm comparing this to the umpteen times I've had to follow that "parent" instance variable up the tree, to figure out where the heck a particular <code>Composite</code> lives, and what the structure is.<br /><br />I can see already that I'm going to need Ctrl+Click to go from the .xmi file to the relevant classes. (Maybe I just need the appropriate EMF editor)<br /><br />I have to wonder what <code>newproject.js</code> is. I can only think it is related to <a href="http://wiki.eclipse.org/E4/JavaScript">writing plug-ins in other languages</a>. I see mention of <a href="http://www.mozilla.org/rhino/">Rhino</a> as the toolkit. Perhaps the <a href="http://www.eclipse.org/birt/phoenix/deploy/reportScripting.php">BIRT</a> team can lend some expertise in this area.<br /><br />I hope to get to the Resource model changes next time.Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com5tag:blogger.com,1999:blog-1968631882469464262.post-7937466993975617902009-02-22T21:18:00.000-05:002009-02-22T21:28:50.372-05:00WelcomeA little about me. I've been a Java developer in the Washington DC area for about 5 years. I started out in the web tier, and began building Eclipse apps in 2005. I took a short hiatus from <a href="http://www.eclipse.org/swt">SWT</a> to work with <a href="http://code.google.com/webtoolkit/">GWT</a> for about a year, then back into Eclipse last spring.<br /><br />I've worked with a wide variety of Eclipse technologies, including <a href="http://wiki.eclipse.org/index.php/Rich_Client_Platform">RCP</a>, <a href="http://www.eclipse.org/modeling/emf/">EMF</a>, <a href="http://www.eclipse.org/gef/">GEF</a>, and <a href="http://www.eclipse.org/birt/">BIRT</a>. Lately I've been spending a lot of time hacking the Equinox <a href="http://wiki.eclipse.org/Equinox_p2">p2</a> component.<br /><br />Over the years, I've accumulated a fair amount of knowledge about the inner workings of Eclipse; I hope to share what I've learned on this blog. And so off we go..Ben Vitalehttp://www.blogger.com/profile/10057954087267715667noreply@blogger.com2