読者です 読者をやめる 読者になる 読者になる

JUnit Plug-in での起動を調べる その 4

今日は、envp という変数からです。

               String[] envp= DebugPlugin.getDefault().getLaunchManager().getEnvironment(configuration);

これを WrpeLaunchConfigurationDelegate#launch メソッドに組み込んで試してみました。

        String[] envp= DebugPlugin.getDefault().getLaunchManager().getEnvironment(configuration);
        if (envp != null) {
            for (String env: envp) {
                System.out.println("Env: " + env);
            }
        } else {
            System.out.println("Envp = null");
        }

これで実行すると

Envp = null

と表示されてしまいます。これじゃ、何の値か分からないですね。困るんだけど、まぁいいや、先に進めよう。

次がやっと VMRunnerConfiguration オブジェクトの生成です。これをおこなっているのが createVMRunner メソッドですが、JUnitBaseLaunchConfiguration クラスではなく、派生クラスの方の JUnitLaunchConfiguration クラスで定義されています。

	protected VMRunnerConfiguration createVMRunner(ILaunchConfiguration configuration, IType[] testTypes, int port, String runMode) throws CoreException {
		String[] classPath= createClassPath(configuration);	
		String progArgs= getProgramArguments(configuration);
		VMRunnerConfiguration vmConfig= new VMRunnerConfiguration("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner", classPath); //$NON-NLS-1$
		String testName= configuration.getAttribute(JUnitBaseLaunchConfiguration.TESTNAME_ATTR, ""); //$NON-NLS-1$
		String testFailureNames= configuration.getAttribute(JUnitBaseLaunchConfiguration.FAILURES_FILENAME_ATTR, ""); //$NON-NLS-1$
		
		// insert the program arguments
		Vector argv= new Vector(10);
		ExecutionArguments execArgs = new ExecutionArguments("", progArgs); //$NON-NLS-1$
		String[] pa= execArgs.getProgramArgumentsArray();
		for (int i= 0; i < pa.length; i++) {
			argv.add(pa[i]);
		}
	
		argv.add("-version"); //$NON-NLS-1$
		argv.add("3"); //$NON-NLS-1$
		
		argv.add("-port"); //$NON-NLS-1$
		argv.add(Integer.toString(port));
		//argv("-debugging");
				
		if (keepAlive(configuration) && runMode.equals(ILaunchManager.DEBUG_MODE))
			argv.add(0, "-keepalive"); //$NON-NLS-1$
		
		// a testname was specified just run the single test
		if (testName.length() > 0) {
			argv.add("-test"); //$NON-NLS-1$
			argv.add(testTypes[0].getFullyQualifiedName()+":"+testName);			 //$NON-NLS-1$
		} else if (testTypes.length > 1) {
			String fileName= createTestNamesFile(testTypes);
			argv.add("-testNameFile"); //$NON-NLS-1$
			argv.add(fileName);
		} else {
			argv.add("-classNames"); //$NON-NLS-1$
			for (int i= 0; i < testTypes.length; i++) 
				argv.add(testTypes[i].getFullyQualifiedName());
		}
		if (testFailureNames.length() > 0) {
			argv.add("-testfailures"); //$NON-NLS-1$
			argv.add(testFailureNames);			
		}
		String[] args= new String[argv.size()];
		argv.copyInto(args);
		vmConfig.setProgramArguments(args);
		return vmConfig;
	}

ちょっとソース追うのたいへんかもしれない ^^;;

地道にやっていきましょう。

まずは createClassPath メソッドですね。

	private String[] createClassPath(ILaunchConfiguration configuration) throws CoreException {
		URL runtimeURL= Platform.getBundle("org.eclipse.jdt.junit.runtime").getEntry("/"); //$NON-NLS-1$ //$NON-NLS-2$
		URL url= Platform.getBundle(JUnitPlugin.PLUGIN_ID).getEntry("/"); //$NON-NLS-1$
		
		String[] cp= getClasspath(configuration);
		String[] classPath= null;
		
		try {
			if (Platform.inDevelopmentMode()) {
				// we first try the bin output folder
				List junitEntries= new ArrayList();
				
				try {
					junitEntries.add(Platform.asLocalURL(new URL(url, "bin")).getFile()); //$NON-NLS-1$
				} catch (IOException e3) {
					try {
						junitEntries.add(Platform.asLocalURL(new URL(url, "junitsupport.jar")).getFile()); //$NON-NLS-1$
					} catch (IOException e4) {
						// fall through
					}
				}
				try {
					junitEntries.add(Platform.asLocalURL(new URL(runtimeURL, "bin")).getFile()); //$NON-NLS-1$
				} catch (IOException e1) {
					try {
						junitEntries.add(Platform.asLocalURL(new URL(runtimeURL, "junitruntime.jar")).getFile()); //$NON-NLS-1$
					} catch (IOException e4) {
						// fall through
					}
				}
				Assert.isTrue(junitEntries.size() == 2, "Required JARs available"); //$NON-NLS-1$
				
				classPath= new String[cp.length + junitEntries.size()];
				Object[] jea= junitEntries.toArray();
				System.arraycopy(cp, 0, classPath, 0, cp.length);
				System.arraycopy(jea, 0, classPath, cp.length, jea.length);
			} else {
				classPath= new String[cp.length + 2];
				System.arraycopy(cp, 0, classPath, 0, cp.length);
				classPath[cp.length]= Platform.asLocalURL(new URL(url, "junitsupport.jar")).getFile(); //$NON-NLS-1$
				classPath[cp.length + 1]= Platform.asLocalURL(new URL(runtimeURL, "junitruntime.jar")).getFile(); //$NON-NLS-1$
			}
		} catch (IOException e) {
			JUnitPlugin.log(e); // TODO abort run and inform user
		}
		return classPath;
	}		

このメソッドも長いなぁ。

普通の CLASSPATH は AbstractJavaLaunchConfigurationDelegate#getClasspath メソッドで取得できるようです。取得できたものを出力させてみたら

        String[] classPath= getClasspath(configuration);
        for (String cp: classPath) {
            System.out.println("CLASSPATH: " + cp);
        }
CLASSPATH: D:\users\sakuraba\runtime-EclipseApplication\sample
CLASSPATH: D:\lg3d\lib\ext\lg3d-core.jar

と出力されました。上がプロジェクトのソースが置いてあるところなので、ちゃんとそれも含まれているようです。

これでいいのにと思うのですが、この後のコードは何なのでしょうか。JUnit Plug-in では Plug-in 自体を CLASSPATH に含めなくてはいけないので、それを考慮したコードになっているようです。

このコードは今は参考にしませんが、いずれ LG3D を起動したままで、後からアプリケーションを起動するようなときに使えそうです。