lg3d-core.jar を CLASSPATH に追加する その 2

それにしても JavaCapabilityConfigurationPage#init の引数 defaultEntries を null にすると rt.jar が加わるというのは不可解なので、ちょっと調べてみました。

defaultEntries が null の場合、JavaCapabilityConfigurationPage#init -> BuildPathsBlock#init -> BuildPathsBlock#getDefaultClassPath という順番でコールされています。

getDefaultClassPath メソッドは次のように記述されています。

	private List getDefaultClassPath(IJavaProject jproj) {
		List list= new ArrayList();
		IResource srcFolder;
		IPreferenceStore store= PreferenceConstants.getPreferenceStore();
		String sourceFolderName= store.getString(PreferenceConstants.SRCBIN_SRCNAME);
		if (store.getBoolean(PreferenceConstants.SRCBIN_FOLDERS_IN_NEWPROJ) && sourceFolderName.length() > 0) {
			srcFolder= jproj.getProject().getFolder(sourceFolderName);
		} else {
			srcFolder= jproj.getProject();
		}

		list.add(new CPListElement(jproj, IClasspathEntry.CPE_SOURCE, srcFolder.getFullPath(), srcFolder));

		IClasspathEntry[] jreEntries= PreferenceConstants.getDefaultJRELibrary();
		list.addAll(getExistingEntries(jreEntries));
		return list;
	}

プリファレンスからとりだして、それを CLASSPATH のエントリーに追加しているんですね。というわけで、これと同じようなコードを書けばいいということは分かりました。が、くせ者なのが list に追加されるオブジェクトは CPListElement だということです。

このクラスも internal なんですよ。なんで、非常に使いにくい。CPListElement クラスを調べてみたのですが、結構複雑。そんなこんなで、これと同じようなコードをもう一度記述するというのも非効率的なような気がしてきました。

じゃあ、どうすればいいか?

本当は JavaCapabilityConfigurationPage によるページが表示されているときにはすでに lg3d-core.jar を CLASSPATH に含ませたかったのですが、それはあきらめました。結局、performFinish メソッドで CLASSPATH に追加しています。

    public boolean performFinish() {
        IRunnableWithProgress op = new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {              
                try {
                    project.create(monitor);
                    project.open(monitor);
                    javaPage.configureJavaProject(monitor);

                    IPreferenceStore store = WrpePlugin.getDefault().getPreferenceStore();
                    String home = store.getString(WrpePlugin.LG3D_RREF_HOME_KEY);
                    Path corePath = new Path(home + CORE_LIBRARY);
                    try {
                        IClasspathEntry[] initialEntries = javaProject.getRawClasspath();
                        IClasspathEntry[] entries = new IClasspathEntry[initialEntries.length + 1];
                        System.arraycopy(initialEntries, 0, entries, 0, initialEntries.length);
                        entries[initialEntries.length] = JavaCore.newLibraryEntry(corePath, null, null);
                        javaProject.setRawClasspath(entries, monitor);
                    } catch (JavaModelException ex) {
                        ex.printStackTrace();
                    }
                } catch (CoreException ex) {
                    ex.printStackTrace();
                    throw new InvocationTargetException(ex);
                } finally {
                    monitor.done();
                }
            }
        };
        
        try {
            getContainer().run(true, false, op);
        } catch (InterruptedException ex) {
            return false;
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
            Throwable realException = ex.getTargetException();
            MessageDialog.openError(getShell(), "Error", realException.getMessage());
            return false;
        }
        return true;
    }

これで実行だ!

CLASSPATH

でも、本当はもっと効率のいい方法があるような気もします...