Architecture-Specific Eclipse Plug-in Fragments
I need to target both win32.x86 and win32.x86_64 architectures when building an RCP plug-in that uses OS.getRegOpenKey(...). The types of the arguments for the method are different for the two architectures.
I understand now that there is no straightforward way to have an x86 or x86_64 fragment (depending upon the build) override a method in my host plug-in.
However, from this post it sounds like a fragment can, for example, add a class that extends a class in the host. And the host plugin can then explicitly use the ClassLoader to find and instantiate the correct subclass from the fragment 开发者_开发知识库included in that architecture's build. What would this look like?
Based on the linked-to post, this is what I have so far (builds without error now for both architectures, and I just need to see if the built 64-bit app will run on 64-bit Windows!):
Use Eclipse's fragment plug-in wizard to create the x86 and x86_64 fragments. The manifests have a couple of extra lines manually added. For example, the important bits of the x86_64 fragment's Manifest.mf:
...
Bundle-SymbolicName: com.company.product.win32.x86_64;singleton:=true
Fragment-Host: com.company.product.win32;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86_64))
Bundle-ClassPath: src/,.
Then, added subclass to the fragment (used the same package name as the super class from the host plug-in, but that probably isn't necessary):
package com.company.product.win32;
import org.eclipse.swt.internal.win32.OS;
import org.eclipse.swt.internal.win32.TCHAR;
/**
* Subclass the host's abstract OSUtilities
*/
public class OSUtilities64 extends OSUtilities {
public String getRegKeyValue (String path, String key) {
long [] phkResult = new long [1];
if (OS.RegOpenKeyEx ((long) OS.HKEY_LOCAL_MACHINE, new TCHAR(0, path, true),
0, OS.KEY_READ, phkResult) != 0) {
...
Same for the OSUtilities32 class.
Added the fragments to the feature.xml containing the host plug-in:
<plugin
id="com.company.product.win32"
os="win32"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.company.product.win32.x86"
os="win32"
arch="x86"
download-size="0"
install-size="0"
version="0.0.0"
fragment="true"
unpack="false"/>
<plugin
id="com.company.product.win32.x86_64"
os="win32"
arch="x86_64"
download-size="0"
install-size="0"
version="0.0.0"
fragment="true"
unpack="false"/>
Then the host plug-in can statically load the appropriate, available class:
/**
* Get class from appropriate fragment
*/
public static OSUtilities getOSUtilities() {
ClassLoader loader = OSUtilities.class.getClassLoader();
try {
Class<?> cls;
try {
cls = loader.loadClass("com.company.product.win32.OSUtilities32");
} catch (ClassNotFoundException e) {
cls = loader.loadClass("com.company.product.win32.OSUtilities64");
}
OSUtilities util = (OSUtilities) cls.newInstance();
return util;
I should use the architecture system property to pick which to instantiate -- later.
精彩评论