Welcome to Planet Eclipse

August 07, 2008

Wayne Beaton
Wayne Beaton

Reviewers and Editors Deserve Love Too!

We have what has been referred to as an “embarrassment of riches” in Eclipse Corner. We have a lot of articles that are either in development, or are ready for publishing. The problem is that we have a bit of a shortage of reviewers and editors. Perhaps one of the problems is that we do not formally recognise the role of reviewer and editor in the process. I’d like to fix that.

A reviewer needs to be an expert in the subject area of the article. Ideally, reviewers are Eclipse committers (but I don’t think that this is an absolute necessity). The reviewer’s job is to make sure that the content of the article is technically correct. Very often, an article crosses the boundaries between Eclipse projects and so more than one reviewer may be required (i.e. one for each project referenced by the article). When the author and reviewer are done iterating over the content, an editor steps in and puts the final touches on the article. An editor is familiar with the subject area, but need not necessarily be an expert in the field (frankly, it’s great when an editor learns something in the process of editing an article). Editors need to have decent English-language spelling and grammar skills.

Do you have what it takes to be a reviewer or editor? It’s easy to do, just take a look at the bugs open against “Articles” in Eclipse Bugzilla, find an article that interests you, add a comment to the effect of “I’d like to [review | edit] this article”, and then immerse yourself in the role.

While I do relish the prospect of formalizing the role of reviewer and editor, I don’t want to formalize the process too much. Read over what the author has written so far, and provide your feedback as comments via the bug system. If you have any questions about the process, or just want to get your opinions registered about this, please add them to Bug 243486.

To make things more interesting for you, reviewers and editors will now get swag as well. You’ll also get explicit credit for your efforts. And the gratitude of a community.

Patrick Paulin
Patrick Paulin

Eclipse RCP Trends


I’ve been having some fun today with Google Insights for Search, and of course my first thought was to examine trends relating to the Eclipse Rich Client Platform. And what did I find? Here is a chart showing historical data beginning in 2004 for the search “eclipse rcp”.

First, this is just awesome data! You can drill down to individual countries, states/provinces or even cities. I could play with this all day, but I really should get back to work!

Unfortunately the news isn’t good for Eclipse RCP. It’s interesting that while Eclipse RCP job postings are trending up, the search statistics are telling a different story. The stats for RCP look even worse when you compare them to Adobe Flex, which many (mistakenly, I believe) think of as a substitute for RCP.

We obviously need to do a much better job promoting Eclipse RCP. There are so many things involved with this, including making the platform easier to use (hopefully the e4 project will help) and also communicating clearly what Eclipse RCP is and why it’s useful. I’ll have something to say about this later point in upcoming posts, but I’d be curious to hear what others have to say. What do you think can be done to better promote Eclipse RCP?

Eclipse Enthusiasts Poznań
Eclipse Enthusiasts Poznań

If you ever had to extend an inherited or undocumented Eclipse based application, weren't you wondering what might be hiding in it? Myriads of misterious extension points and handy services. Since Eclipse 3.4 it's easy to deep dive into Eclipse extension points and services thanks to PDE Plug-in Registry view.



But as most of Eclipse based applications use Eclipse 3.3 or even 3.2, now it's getting easier to use Plug-in Registry in those older releases too, thanks to this bug.
Following screenshot presents 3.4 Plug-in Registry view installed in IBM Rational Software Modeler, based on Eclipse 3.3. Revealed are all GMF editors tool palettes with their IDs and names, which makes it easy to add even more tools!

Doug Gaff
Doug Gaff

I love OCD

No, I'm not talking about locking the front door exactly 3 times before going to bed or using a new bar of soap each time I wash my hands à la Jack Nicholson. I'm talking about On-Chip Debugging – using JTAG tools for device software debugging.

I got my start at Wind River working on JTAG-based debuggers. A couple of years ago, my team integrated Wind River's JTAG emulators into our Eclipse-based product, Wind River Workbench. It was quite a challenge connecting hardware debugging to a debugging framework focused on application development, and the Device Debugging and Target Management projects spun out of that effort.

Today I manage our Eclipse open source contributions, but I still sit next to my OCD buddies. When they're not nervously clicking their retractable pens, they're writing firmware for our JTAG emulators. Today, they released a cool new emulator that blows away their previous products:



If you're a "desktop refugee" who's just started writing software for devices, you're likely only familiar with agent-based debugging. A debug agent is the hidden software app that runs with your OS and helps you debug your application. But to get that OS running on a piece of custom hardware, you need JTAG. JTAG allows you to stop the entire system by stopping the processor itself, to directly debug kernel code/ device drivers / ISR's, and to directly configure processor and peripheral registers.

However, JTAG is great for application development too. I personally think its coolest feature is the ability to trace every line of software executed on a running system without any instrumentation in the code. Modern embedded processors, in addition to supporting JTAG-based debugging, also support JTAG-based trace. Software crashing? Turn on trace and see exactly when the code went out to lunch. Getting a hardware exception? Turn on trace and see what code was executing immediately prior to the interrupt. Need to profile a specific set of routines or examine code coverage? All of this can be done with JTAG Trace.

This is "god mode" access to your hardware, and it's why I love OCD. Still using printf? As Nelson would say:




Anthony Hunter
Anthony Hunter

Eclipse Galileo Simultaneous Release

For those who missed the ongoing discussion, it is official. Galileo will be the fourth Eclipse simultaneous release following Callisto, Europa, and Ganymede.

Io was due up to be the name of the release as the fourth of the Galilean moons, but given that "Io" looks a lot like "10" and "I/O", the planning council went with the name of the astronomer who discovered these four moons. An excellent choice.

Cheers to Galileo.






August 06, 2008

Dave Carver
Dave Carver

Continuous Integration Anti-Patterns

Martin Fowler's "Continous Integration" article should be required reading. Particularly if you are working with a global team of developers in disparate locations. It defines a set of patterns and rules for helping to keep builds clean and working.

What I find more interesting besides patterns, are Anti-Patterns. Those things that people do that just don't work. In particular, I've found a couple of articles of late that discuss Anti-Patterns when it comes to continuous integration.

These three articles cover the most common reasons why an integration build will commonly fail. I'm sure most of those who follow the process of continuous integration have fallen into one of more of these anti-patterns at some point. It is important though that once we fall into them we recognize it and try to work our way out of them. Keeping a build clean especially with a dispersed project team is critical to knowing that the system is working, and that unforseen changes haven't crept in. It is especially important when there are inter-related dependencies.

If a build fails for any reason, it should be given higher priority over what ever you are working on. A failing build means there is something wrong. As Paul Duval says:

...builds become increasingly more troublesome to fix the longer they stay broken. This is because there are more files, more changes, and more dependencies that make the isolation of the defect difficult.


Keep your builds clean and it will make your development process that much easier. If you are using Cruise Control to run your builds, then check out the 3rdPartyCCStuff for ways to monitor the builds.

Chris Aniszczyk
Chris Aniszczyk

Happy Birthday Eclipse Evangelist!

For those who don't know, it's our lovely Eclipse evangelist's birthday today.



Happy Birthday Wayne Beaton!

I think he turns a spry 28 or something :)

Suresh Krishna
Suresh Krishna

Beware of writing regex and string functions


Recently i was involved in an issue took a week to come to know the root cause. In the end its an eye opener to many who does not give importance to string functions and regex. “Regular expressions and String functions are quite powerful in any language; however utmost importance should be given to such code.”

The issue is very simple. Set of Java Files need to processed to get some annotations and other proprietary stuff and also separate the main class names and inner class names. The customer created Business Entities which may contain inner classes and are passed through a pre-processor. Problem occurs in a particular case when the File name is “BlaSomeClassName_Bla.java” and it contains a inner class “SomeClass”.

–>Inner class name is SIMILAR to main class name.

Lets look at the following code and especially the line 6. This line tries to match the class names given by qdox (java source parser) with the java source file that is currently being processed.

1     if (classes.length == 1) {
2         _javaClass = classes[0];
3     } else {
4         for (int i = 0; i < classes.length; i++) {
5             JavaClass aClass = classes[i];
6             if (aSourceFile.getName().matches(".*" + aClass.getName() + ".*")) {
7                 _javaClass = classes[i];
8                 break;
9             }
10        }
11    }

This is the regular expression that took up my days and nights which rarely has any sort of consistency in execution. In the above example the source that is being processed is the “BlaSomeClassName_Bla.java” and the class names that you get from qdox will be “BlaSomeClassName_Bla” and “SomeClass”. And now probably you would have guessed. In the array “classes”, if the “SomeClass” comes as the first element you are screwed. The regular expression matches the “BlaSomeClassName_Bla” and the processing class is taken as “SomeClass”. Where as the right processing class is “BlaSomeClassName_Bla”.

This issue took quite a few days to really understand and get to the bottom of the code. Many many thanks to eclipse which enables a cool debugging. Conditional debugging is very useful in such scenarios where you would not want to wait for a long time to see the special case. Instead, introduce the right condition and rest is taken care by eclipse. This is what makes the eclipse my favorite IDE.

Do you have any such experiences with strings and regex ?

Doug Schaefer
Doug Schaefer

How's build working for you?

It's been a crazy couple of months for me. The list of things I need to do has been badly encroaching on my time for Eclipse community work. But it's all been good and we're working on some really cool stuff with p2 internally here at Wind River which should turn into community work as well anyway.

But it's getting time to start my work on e4 and the Eclipse resource model. We've talked a lot in the past about the need for flexibility there and to support other resource models that don't necessarily map to the underlying file system. Even in the last few days we've received inquiries on the cdt-dev list about supporting Visual Studio-style projects in this manner (from a guy with an e-mail address of nvidia.com - quite interesting). So this is what we've meant by flexible resources and what we plan on addressing.

The question I'm starting to ask myself is whether we should be looking at the build side of the resource model as well. If you come from the Makefile centric view of the world, the Eclipse build system is very bizarre indeed. I'm not sure of the history of how it got to be that way, but it was our first real interaction with the Eclipse Platform team, to somehow get Eclipse to build CDT projects correctly. There's still a lot of magic there that probably could be simplified if we made the build model more flexible as well.

Also we have a hell of a time co-ordinating loading the CDT build model data from our magic .cproject file at the right time and in a scalable and non-deadlockable way. Sometimes I just wish that the .project file and the code that manages it was more flexible as well so I can have our build data loaded at the same time the rest of the project information is loaded. (Yes you can do a little of that now but not easily with the complex data we have for our build configurations, tool chains, option settings, etc).

Anyway, I don't know how many people are building IncrementalProjectBuilders out there (and, yes, the weirdness does start there). But I was wondering if other plug-in developers are also facing issues like this.

Kenn Hussey
Kenn Hussey

On Search Providers...

I mentioned that I spent a lot of my time recently on a deep dive into one of Embarcadero's products that's about to release in the coming weeks. I had planned on giving a "sneak peak" as to what it's all about, but it turns out that Greg beat me to it (thanks, Greg!).

Rather than repeat everything that Greg said, I'll focus on a lesser known aspect of one of the portal's main features. Despite the incredible value of its shared reports, explore dashboard, ad hoc query interface, and administration console, perhaps the most popular (and most scrutinized!) feature of the portal thus far has been its search capability.

One of the cool things (at least in my mind) about the search capability of the ER/Studio Enterprise Portal is that, like other Web-based search interfaces, it can be integrated into the search bar of your favorite browser. I'll walk through the steps to do this for Internet Explorer as an example.

1. Select the 'Find More Providers...' item from the search bar's drop-down menu.



This will take you to a Web page where can choose from among several exiting providers or create your own.

2. From a different browser window, type 'TEST' into the search box of the ER/Studio Enterprise Portal and hit .

This will take you to the Search Results page.



3. Copy and paste the URL from the Search Results page (the "&x=8&y=6" portion at the end isn't necessary), specify a name for the new search provider, and press the 'Install' button.



This will open a dialog asking you to confirm that you want to add the search provider (click 'Add Provider').



4. Choose the new search provider from the search bar's drop-down menu, type in your text, and away you go!



To avoid having to log into the portal each time you want to search, you can also add your user name and password to the URL before pressing the 'Install' button in step 3 above by appending, for example, the string "&userid=MyUserID&password=MyPassword".

Wayne Beaton
Wayne Beaton

SWT Graph

The SWT Graph Source Forge project provides some pretty sophisticated interactive graphical technology for Eclipse RCP-based applications. The sample images shown on the examples page are pretty cool, but the description of the underlying technology seems even cooler. Layered canvases are a natural and very powerful extension to SWT.

It’s licensed under the LGPL. Make sure you review that license carefully!

Donald Smith
Donald Smith

A Great Scholarship Opportunity For Eclipse Ecosystem Research

Lots of great companies in the Ottawa area have spun out of the hard work and entrepreneurship of Carleton University. OTI and The Object People are just two that come to mind (both organizations ultimately fostered the teams that built a lot of the Eclipse Platform and EclipseLink respectively).

Carleton's "Technology Innovation Management" masters program (TIM) is fantastic - over the last few years we've worked with a number of students and faculty in this program, and have learned a lot from their research. Lots of great stuff on ecosystems, open source business models, collaboration models, intellectual property models and so on.

Here is the good news - the TIM program has a number of scholarships available starting as early as this fall -- and you can do this while continuing your current job. A great way to earn a Masters Degree while diving deeper into the dynamics behind Eclipse. A great career boosting opportunity.

If I didn't have two Masters degrees already, I'd be all over this :) If you're at all interested, please check out more about the program and feel free to contact me if you have any questions.

- Don

Dave Carver
Dave Carver

Mylyn Mantis Connector 3.0 Final available

Mylyn-Mantis 3.0 available.

Mylyn-Mantis is a Mylyn 3.0 connector for the Mantis Bugtracker. It is licensed under the Eclipse Public License. We now have all functionality of the Mylyn 2.0 connector working, plus a few additional bug fixes:

  • Fixed 'Resolving issue does not set status'
  • Map priority and severity level (thanks to Jim Allers)
  • Removed duplicate jar files from core.jar ( thanks to Edward Rudd )
  • Fixed users with 'reporter' access level appearing in 'assign to' field
This version is designed for Eclipse 3.4 and Mylyn 3.x. It may be retreived using Software Updates at:

http://mylyn-mantis.sourceforge.net/eclipse/update/site.xml

Eugene Kuleshov
Eugene Kuleshov

Geting most out of configuration details

As part of my work on Maven Integration for Eclipse I have to investigate various problems reported by the users. Eclipse Platform is a very powerful environment, but at the same time, its power makes some things hard to deal with. Because of its extensibility users can have various features installed and they also use wide range of platform releases. For Maven integration we choose to support Eclipse 3.2, 3.3 and 3.4 and each of those have their own quirks and API incompatibilities that need to be worked around, and it is important to get information from the user about the actual Eclipse configuration.

While investigating solution how to provide a better user assistance, I discovered an interesting extension available in Eclipse that allows to plug in custom information into the standard UI for retrieving Eclipse configuration details. It is not necessarily this would be the actual solution we'll use in Maven integration to provide user assistance, but it is definitely worth exploring. Let's see what we can get out of it.

Eclipse configuration details viewer is a handy little feature that allow to capture IDE configuration details and it is available from Help / About Eclipse SDK / Configuration Details:

These configuration details have information about installed features and active plugins, system properties, workbench and project settings and some other info that helps a lot while investigating bug reports. However, with very little effort you can get more out of this feature.

What makes this feature even more interesting is that plugins can contribute additional sections to configuration details using org.eclipse.ui.systemSummarySections extension point available since Eclipse 3.0.

For example, when investigating concurrency issues, we often have to ask users to submit thread dumps from their Eclipse instance and unfortunately it is not exactly trivial task for an average user. User would either have to run Eclipse with console, or use JConsole, or jstack tools from JDK, which is often a hassle. So, it would be really handy to see the thread dump right in the system configuration details. Luckily it is really easy to add this information there.

First of all we need to add declaration for the extension point:
   <extension point="org.eclipse.ui.systemSummarySections">
      <section class="org.javatx.eclipse.info.ThreadDumpSection"
               sectionTitle="Thread Dump"/>
   </extension>
The ThreadDumpSection class need to implement single method write() that will write relevant information to the provided Writer. We can use JMX API from Java 5 to capture all required information. For example:
public class ThreadDumpSection implements ISystemSummarySection {

  public void write(PrintWriter w) {
    OperatingSystemMXBean osMXBean = ManagementFactory.getOperatingSystemMXBean();
    int availableProcessors = osMXBean.getAvailableProcessors();

    w.format("Available processors: %s\r\n", availableProcessors);
    
    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
    
    ThreadInfo[] threads = threadMXBean.dumpAllThreads(true, true);
    for (ThreadInfo info : threads) {
      long threadId = info.getThreadId();
      String threadName = info.getThreadName();
      State threadState = info.getThreadState();
      
      long blockedCount = info.getBlockedCount();
      long waitedCount = info.getWaitedCount();

      w.format("%s : %s  State: %s  Blocked: %s  Waited: %s\r\n", //
          threadId, threadName, threadState, blockedCount, waitedCount);

      long lockOwnerId = info.getLockOwnerId();
      if(lockOwnerId>-1) {
        String lockOwnerName = info.getLockOwnerName();
        String lockName = info.getLockName();
        w.format("    Lock: %s by %s\r\n", lockName, lockOwnerName);
      }
      
      for (StackTraceElement e : info.getStackTrace()) {
        int line = e.getLineNumber();
        String className = e.getClassName();
        String methodName = e.getMethodName();
        String fileName = e.getFileName();
        if(line<0) {
          w.format("  %s.%s(%s)\r\n", className, methodName, fileName);
        } else {
          w.format("  %s.%s(%s:%s)\r\n", className, methodName, fileName, line);
        }
      }
      w.write("\r\n");
    }
    
    w.write("\r\n");
  }
}
This is basically it. Once this compiled and deployed with your plugin, the new section will simply appear in the configuration details and your users won't have to struggle with getting thread dumps anymore.

As you can see, this little feature can be used to capture additional configuration details, which is extremely important when working on integrations with other systems.

Peter Kriens
Peter Kriens

Classy Solutions to Tricky Proxies

Though the quest for reusable systems is the guiding principle in my life, I only recently start to understand the reason for some of the mechanisms in Spring. For example, I start to see that the whole Aspect Oriented Programming (AOP) business is not about aspect oriented programming, but it is about hammering an existing code base into its intended slot. Unfortunately, some of the slots are square while the code bases are quite round. Therefore, proxying is an important aspect of developing a system by making a round object look square, or vice versa.

The bad news is that OSGi is not making this easier. The OSGi framework was designed with green field applications in mind that would follow proper modularity rules and communicate through services. In a perfect OSGi world, bundles are highly cohesive and are coupled through their services. In the real world, class loaders are (ab)used for configuration and ad-hoc plugin systems. Some of those problems are quite complex.

Today, I was asked about the following problem.

A company is using Spring. One of their bundles referred to a service that another bundle had registered. Spring has decided that services are too jumpy, so they proxy the service object for their clients and add some mixins in the proxy that handle the situations when a service goes away (Spring also adds some other mixins).

Creating a proxy is class loader magic. You take a set of interfaces (the mixins) and generate the byte codes for a class that implements all these interfaces. The implementation of the interface methods forwards the call to a handler object using the object, the method that was called and the arguments.

If you generate the byte codes for a class, you need to define this class in a class loader and this is where the modularity comes into play. In a traditional Java application you can just take the application class loader and define this new class in this class loader. The application class loader usually has full visibility. In a modular system, however, visibility is restricted to what you need to see. In OSGi, the imported packages are all a bundle can see (at least, when you want to work modular and not use dynamic imports buddy class loading).

The catch is that the proxy requires access to all the mixin classes. However, some of these mixin classes come from one bundle, and some come from another bundle. There is likely no class loader that can see both bundle class spaces unless that bundle specifically imports the correct interfaces. However, if a client bundle gets one of his objects proxified, then he has no knowledge of the mixins (that is the whole idea). It would be fundamentally wrong to import the interface classes while he is oblivious of them. However, the bundle that generates the proxy might know the mixin classes but it is unlikely it knows the classes of the target object. If the proxy generator was implemented as a service (as it should be) then there would even be 3 bundles involved: the proxy generator, the bundle needing the proxy, and the client bundle.

Spring solved this problem with a special class loader that chained the class loader from the client bundle together with the class loader of the Spring bundle. They made the assumption that the Spring bundle would have the proper imports for the mixin classes it would provide and the client bundle would have knowledge of the proxied object's classes.

So all should work fine? Well obviously not or I would not write this blog.

The generated proxy class can see the Spring bundle with the interface classes and it can see the all the classes that the client bundle can see. In the following picture, the client bundle imports the service interface from package p, but it does not import package q which is used in package p. If you create a proxy for a class in package p, it will need access to package q, and the client bundle can not provide this.



For example, assume the following case:

javax.swing.event.DocumentEvent de =
(DocumentEvent) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class
[]{DocumentEvent.class}, this );

The DocumentEvent is from the javax.swing.event package. However, it uses classes from the javax.swing.text package. Obviously the bnd tool correctly calculates the import for the DocumentEvent class. However, when the generated proxy class is instantiated, it will need access to all the classes that the DocumentEvent refers to: the super class, classes used as parameters in method calls, exceptions thrown, etc. These auxiliary classes are crucial for the DocumentEvent class, but they are irrelevant for the client bundle, unless these classes are actually used in the client bundle, where they would be picked up by bnd.

So, if the client bundle does not import javax.swing.text then you will get a ClassDefNotFoundError when you try to instantiate the proxy class. This error gets generated when the VM sees the reference to class in the javax.swing.text package and tries to load it through the proxy class' class loader (that is why this is an error, it happens deep down in the VM).

To be specific, this is exactly as it should be in a proper modular system. The client should not be required to import classes that it does not need. The onus is on the proxy generating code to do it right.

Fortunately, the solution is not that hard but it highlights how easy it is to make the wrong assumption, believe me, these Spring guys are quite clever.

Just take a step back and look at the problem.

Do we need visibility on the bundle level here? Look at the information given to the proxy generator: a set of mixin classes. It does not really matter from what bundle these interfaces classes come from; the class loader that we need must be able to see each of the interface classes class loaders. By definition, those class loaders can see the right class space.

So instead of chaining the bundle class loaders, the problem can be solved by having a class loader that searches each of the class loaders of the used mixin classes.

For the Advanced


The sketched model is too simplistic because there is the cost of a class loader per generated proxy. Even though enterprise developers seem to live in a wonderful world where memory is abundant, as an old embedded geezer such abuse of class loaders worries me. Though it is possible to use a single combined class loader by keep adding the required class loaders but this raises the question of life cycle. Such an über class loader would pin an awful lot of bundle class loaders in memory and it will be very hard to not run into class space consistency problems because over time this class loader will see all class spaces. That is, this approach brings us back to all the problems of today's application servers.

I have not tried this, but the solution is likely to make the proxy generator service based. Not only will this make it easier to plugin different generators, it also means that the generator is bundle aware. It can then create a combining class loader for each bundle that uses the Proxy Generator service. This class loader will then be associated with the class space of that bundle and should therefore not be polluted with classes from other class spaces. In the Spring case, this would be the client bundle, not the spring bundle. The reason is, is that the spring bundle could be used from different class spaces.

However, the proxy generator must track any bundle that it depends on. That is, it must find out which bundle's export the interface classes and track their life cycle. If any of these bundles stop, it must clear the client's combining class loader and create a new one when needed. This will allow the classes from the stopped bundle to be garbage collected.

Peter Kriens


For the hard core aficionados, some code that demonstrates the problem:

First a base class that acts as activator. This base class calls a createProxy method in the start method. This is then later extended with a proxy generation method that fails and one that works ok.


package aQute.bugs.proxyloaderror;
import java.lang.reflect.*;
import javax.swing.event.*;
import org.osgi.framework.*;

public abstract class ProxyVisibility implements BundleActivator,
InvocationHandler {

public void start(BundleContext context) throws Exception {
try {
DocumentEvent de = createProxy(this, DocumentEvent.class);
System.out.println("Succesfully created proxy " + de.getClass());
} catch (Throwable e) {
System.out.println("Failed to create proxy" + e);
}
}

public void stop(BundleContext context) throws Exception {
// TODO Auto-generated method stub

}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}

abstract protected T createProxy(InvocationHandler handler,
Class primary, Class... remainder);

}


The following class uses the base activator but uses only the client bundle's class loader. Trying to create the proxy will therefore fail because this class loader can not see the javax.swing.text package.


package aQute.bugs.proxyloaderror;
import java.lang.reflect.*;

public class ProxyLoadError extends ProxyVisibility {

@SuppressWarnings("unchecked")
public T createProxy(InvocationHandler h,
Class primary, Class... others) {

Class parms[] = new Class[1 + others.length];
parms[0] = primary;
System.arraycopy(others, 0, parms, 1, others.length);

return (T) Proxy.newProxyInstance(getClass().getClassLoader(), parms,
h);
}
}


And at last, the solution. The following class extends the base activator and creates a proxy that uses a Combined Class Loader. This loader traverses all the class loaders of the mixin classes.


package aQute.bugs.proxyloaderror;
import java.lang.reflect.*;
import java.lang.reflect.Proxy;
import java.net.*;
import java.util.*;

public class ProxyLoadOk extends ProxyVisibility {

@SuppressWarnings("unchecked")
public T createProxy(InvocationHandler h, Class primary,
Class... others) {
CombinedLoader loader = new CombinedLoader();

Class parms[] = new Class[1 + others.length];
parms[0] = primary;
System.arraycopy(others, 0, parms, 1, others.length);
for (Class c : parms) {
load