Setup Eclipse Workspace in Java Code - java

I am writing a JUnit Plug-In Test, which will open a Java Project from the WorkSpace and pass it to a third party library for further processing. This is what I have so far:
#Test
public void testJavaProjectForwarding() {
try {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IWorkspace workspace = root.getWorkspace();
Map<String, IJavaProject> javaProjects = new HashMap<>();
System.out.println("Nr. of projects: " + javaProjects.size());
for(IProject project : workspace.getProjects()) {
if(project.isOpen() && isJavaProject(project)) {
IJavaProject javaProject = JavaCore.create(project);
javaProjects.put(project.getName(), javaProject);
}
}
System.out.println("Nr. of Java projects: " + javaProjects.size());
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I print out first the number of overall projects and second the number of Java projects. Both outputs are, however, 0. This is due to the empty workspace when running a Plug-in Test. My question is: how can I setup the Plug-in Test workspace to include projects? Do I have to do it in the Launch Configuration or can I add them programmatically in the test somewhere? Thanks for your help!

Create a project handle with
org.eclipse.core.resources.IWorkspaceRoot.getProject(String) (returns
IProject)
Load prepared project description:
org.eclipse.core.resources.IWorkspace.loadProjectDescription(IPath)
(returns IProjectDescription, takes a path to .project file as argument)
Actually create a project reference in workspace:
org.eclipse.core.resources.IProject.create(IProjectDescription,
IProgressMonitor)
Open the project: org.eclipse.core.resources.IProject.open(int,
IProgressMonitor)
Example: org.eclipse.ui.internal.wizards.datatransfer.WizardProjectsImportPage.createExistingProject(ProjectRecord, IProgressMonitor). It shows how to copy source project, so that unit tests don't change it. Instead of using precreated (with Eclipse, for example) project description you can create one from scratch.

Related

Make custom Gradle task, that generates code, run on IDE import

Since there is no Gradle plugin for axis2 (a wsdl code generator), I called an Ant task in a custom Gradle task.
As of now ./gradlew build generates the code, and ./gradlew clean deletes it. Also, the code is only generated if changes in the input file(s) or in the output directory are detected.
The only problem I'm having is that the code is not generated automatically when the project is imported into an IDE.
How do I need to change the build.gradle.kts below in order to have the IDEs (currently IntelliJ, but I would also like support for Eclipse) generate the code on import?
plugins {
id("base") // needed for delete
}
val axis2 by configurations.creating
dependencies {
axis2("org.apache.axis2:axis2-ant-plugin:$axis2Version")
axis2("org.apache.axis2:axis2-xmlbeans:$axis2Version")
}
val wsdl2Java by tasks.registering {
group = "build"
description = "Creates Java classes and resources from WSDL schema."
inputs.files(fileTree("$projectDir/src/main/resources/wsdl"))
outputs.dir("$projectDir/generated/")
doLast {
ant.withGroovyBuilder {
"echo"("message" to "Generating Classes from WSDL!")
"taskdef"("name" to "codegen", "classname" to "org.apache.axis2.tool.ant.AntCodegenTask", "classpath" to axis2.asPath)
"codegen"(
"wsdlfilename" to "$projectDir/src/main/resources/wsdl/MP12N-H-HOST-WEB-SOAP.wsdl",
"output" to "$projectDir/generated/",
"targetSourceFolderLocation" to "src/main/java",
"targetResourcesFolderLocation" to "src/main/resources",
"packageName" to "de.hanel.com.jws.main",
"databindingName" to "xmlbeans")
}
}
}
val deleteGenerated by tasks.registering(Delete::class) {
delete("$projectDir/generated/")
}
tasks {
compileJava {
dependsOn(wsdl2Java)
}
clean {
dependsOn(deleteGenerated)
}
}
java {
sourceSets["main"].java {
srcDir("generated/src/main/java")
}
sourceSets["main"].resources {
srcDir("generated/src/main/resources")
}
}
You can mark any task or run configuration to be activated before/after Gradle import or IDE make:
I have a working solution now. Both Eclipse and IntelliJ generate the source code on import.
First we add the IDE-specific plugins.
apply {
plugin("idea")
plugin("eclipse")
}
Then we get the corresponding IDE tasks and add our own task, that was defined in val wsdl2Java, as dependency
// find by name (in tasks container), since a module is also called 'idea'
project.tasks.findByName("idea")?.dependsOn(wsdl2Java)
project.tasks.findByName("eclipse")?.dependsOn(wsdl2Java)
The only problem is that apparently Eclipse can't handle
java {
sourceSets["main"].java {
srcDir("generated/src/main/java")
}
sourceSets["main"].resources {
srcDir("generated/src/main/resources")
}
}
But that's a different question.
UPDATE
The code block below tells Eclipse to include the generated sources
eclipse {
classpath {
plusConfigurations.add(configurations.findByName("compile"))
}
}
and this tells IntelliJ to mark the generated, and already included, sources as generated
idea {
module {
generatedSourceDirs.add(file("generated/src/main/java"))
}
}

How to collapse/expand Eclipse resources tree (Project Explorer) in Java code?

I'm writing a plugin for Eclipse and I been trying without success to figure out how to collapse or expand workspace's resource tree.
For example, to refresh my whole workspace I wrote the code:
for(IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()){
try {
project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
} catch (CoreException e) {}
}
But After it I want to expand the whole tree and I can't figure out how to do this.

NoClassDefFoundError when attempting to compile main class in Java program, while all resources are imported

I'm creating a small app to send messages to phone numbers using google voice. I made a simple test case that works in Eclipse and can send out messages as expected. However, when I try to run it on a terminal, I keep running into issues. Here is the main class I've written:
import java.io.IOException;
import com.techventus.server.voice.Voice;
public class main_WUB {
public static void main(String[] args) {
// TODO Auto-generated method stub
String username = "wake.up.bot.acc";
String password = "wakeupbotacc";
String originNumber = #;
String pavlePhone = #;
String wakeupMessage = "txt from main_WUB";
try {
Voice voice = new Voice(username, password);
voice.sendSMS(pavlePhone, wakeupMessage);
System.out.println("IT WORKED?");
//voice.call(originNumber, pavlePhone, "1");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I've transferred the class into a remote server to test on a linux machine, however, these are the issues I've come up against. When I try to run the main class using
java main_WUB
it returns an exception, stating
Exception in thread "main" java.lang.NoClassDefFoundError: com/techventus/server/voice/Voice at main_WUB.main<main_WUB.java:18> ...
What confuses me is that I ran into this error beforehand in eclipse, and fixed it by importing the reference library in which com.techventus.server.voice.Voice is contained. Now I'm running into the same issue when trying to compile directly. Is there a way to fix this? What am I missing in my command? Any help would be appreciated.
create a jar file for your entire project in eclipse. Procedure for making jar file in eclipse -> right click on your project -> export -> java -> runnable jar file -> select main_WUB in launch configuration drop down list box -> select radio button "extract required libraries into generated jar" -> finish.
now open cmd promt -> goto the path where jar is there -> then give the command "java -jar main_WUB"
It should work.
You need build the JAR with all Libs (dependences) includes.
When you build your project in Eclipse, use the option 'Build with dependences'

my eclipse plug-in creates endless workspace building loops, probably job related

I have created a plug-in to hook into the save action and create a minified javascript file of an edited javascript file. You can see the full code in this question: eclipse plugin does not work after update to juno (eclipse 4)
Problem is that since Juno this plug-in creates endless loops in the workspace building process.
It first starts to minify a file I did not change at all. This file creates an endless loop in the build. When it finished minifing the file it starts a new workspace build and minifies the file again and so on.
But this gets even worse after some time, especially on a new eclipse start. Suddenly there are a dozen of files it minifies I have never touched.
If I uninstall my plugin, then let eclipse build the workspace, reinstall my plug-in it works again. But after a while this starts all over.
I think it is related to the way I handle the job to create the file, see below. Maybe something has changed here with Juno? But I fail to find any information about that.
Job compileJob = new Job("Compile .min.js") {
public IStatus run(IProgressMonitor monitor) {
public IStatus run(IProgressMonitor monitor) {
byte[] bytes = null;
try {
bytes = CallCompiler.compile(fullLocation.toString(), CallCompiler.SIMPLE_OPTIMIZATION).getBytes();
InputStream source = new ByteArrayInputStream(bytes);
if (!newFile.exists()) {
newFile.create(source, IResource.NONE, null);
} else {
newFile.setContents(source, IResource.NONE, null);
}
} catch (IOException e) {
e.printStackTrace();
} catch (CoreException e) {
e.printStackTrace();
}
return Status.OK_STATUS;
}
};
compileJob.setRule(newFile.getProject());
compileJob.schedule();
You need to set newFile to derived. A derived file is one that is created implicitly by the workspace during a build and it should be wiped away during a clean (since it can be recovered during the next build).
You can call the setDerived method on IResource:
org.eclipse.core.resources.IResource.setDerived(boolean, IProgressMonitor)
or when you create the file, it can be created as derived, though a call like this:
newFile.create(stream, IResource.DERIVED, monitor);
But, you cannot set the DERIVED flag through setContents, you must explicitly call setDerived(true) in that case.
From the docs:
A derived resource is a regular file or folder that is
created in the course of translating, compiling, copying, or otherwise
processing other files. Derived resources are not original data, and can be
recreated from other resources. It is commonplace to exclude derived
resources from version and configuration management because they would
otherwise clutter the team repository with version of these ever-changing
files as each user regenerates them.

Creating a Eclipse Java Project from another project, programatically

I would like to create a Java project from another Java project, using some script or Java methods from an Eclipse library, whether it exists. An alternative to this can be duplicating a previously manually-created project. Is there any approach to this?
Thanks.
I believe you can make use of IProject#copy (inherited from IResource.copy)
Adding to Alexander Pavlov's answer, I found that a little extra work is required to copy the project properties (such as referenced projects) in addition to just copying the project files.
public static IProject copyProject(String projectName) throws CoreException {
IProgressMonitor m = new NullProgressMonitor();
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IProject project = workspaceRoot.getProject(projectName);
IProjectDescription projectDescription = project.getDescription();
String cloneName = projectName + "_copy";
// create clone project in workspace
IProjectDescription cloneDescription = workspaceRoot.getWorkspace().newProjectDescription(cloneName);
// copy project files
project.copy(cloneDescription, true, m);
IProject clone = workspaceRoot.getProject(cloneName);
// copy the project properties
cloneDescription.setNatureIds(projectDescription.getNatureIds());
cloneDescription.setReferencedProjects(projectDescription.getReferencedProjects());
cloneDescription.setDynamicReferences(projectDescription.getDynamicReferences());
cloneDescription.setBuildSpec(projectDescription.getBuildSpec());
cloneDescription.setReferencedProjects(projectDescription.getReferencedProjects());
clone.setDescription(cloneDescription, null);
return clone;
}

Categories