Creating a new Java project - java

I am able to create a default project in PDE just like mentioned here.
However I want to know how to create a Java project. How can I do that?

As a minimum you need to add the Java project nature to the project you create. Use something like:
private void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException
{
IProjectDescription description = proj.getDescription();
String[] prevNatures = description.getNatureIds();
String[] newNatures = new String[prevNatures.length + 1];
System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
newNatures[prevNatures.length] = natureId;
description.setNatureIds(newNatures);
proj.setDescription(description, monitor);
}
The nature id for a Java project is 'org.eclipse.jdt.core.javanature' (also in the JavaCore.NATURE_ID constant).
Note that this does not add the various builders that are normally used in a Java project. The IProjectDescription.setBuildSpec method adds those in a similar way. Create a command for the build spec with:
ICommand command = description.newCommand();
command.setBuilderName(builderID);
where 'builderId' is 'org.eclipse.jdt.core.javabuilder' for the main Java builder (JavaCore.BUILDER_ID constant).
All this information is stored in the '.project' file in the project root folder. This is an XML file which you can look at to see the set up of existing projects.

Window->Open Perspective->Java
then
File->New->Java Project (you may have to go via "Project..." to get to the "Java Project" option)

Please refer to New Project Creation Wizards
On the Plug-in Project page, use com.example.helloworld as the name
for your project and check the box for Create a Java project (this
should be the default). Leave the other settings on the page with
their default settings and then click Next to accept the default
plug-in project structure.

Related

Invoking Remote Systems LPEX Editor using java

We have a set of plugins installed in RDI where they display a list of native RPGLE programs and have got a set of classes that invoke the LPEX editor to allow editing the source file in the traditional Library/SoureFile/Member settings.
I now want to extend this to be able to add/edit RPGLE source in the IFS but cannot find the IBM classes that allow this.
For the normal native source the code is
IQSYSMember memberObj;
IBMiConnection iSeriesConnection = RSEConnectionFactory.getISeriesConnection(connection);
memberObj = iSeriesConnection.getMember(
a.getSourceLibrary(),
a.getSourceFile(),
a.getSourceMember(),
null);
QSYSEditableRemoteSourceFileMember editableMember = new QSYSEditableRemoteSourceFileMember(memberObj);
editableMember.open(Display.getCurrent().getActiveShell(), false);
Obviously for source that are in IFS, all I have is a path (/home/path/QRPGLESRC/nnn.RPGLE).
I know I can go to Remote System Explorer and right hand click and select "Open with Remote Systems LPEX Editor" but need to do this from my plugins.
Anyone know which IBM classes allow this to happen?
Many thanks.
Use the open(boolean,progressmonitor) method on QSYSEditableRemoteSourceFileMember
This has fixed my issue:
FileServiceSubSystem fileService = LpexHelper.getFileServiceSubsystem(iSeriesConnection);
IRemoteFile remoteFile = fileService.getRemoteFileObject(path, new NullProgressMonitor());
SystemEditableRemoteFile file = new SystemEditableRemoteFile(remoteFile);
if (file.exists()) {
file.open(Display.getCurrent().getActiveShell(), true);
}

Liferay changes made to source code through ext plugin are not taking place

I needed to override portalLDAPImporterImpl.java addUser() method to perform some action after a user is imported from LDAP and added to Liferay. I followed these steps (Eclipse Environment):
Created Ext plugin project name customLdap;
In docroot/WEB-INF/ext-impl/src I created a package name com.liferay.portal.security.ldap
There I create my CustomPortalLDAPImporterImpl.java class extending portalLDAPImporterImpl.java and override the method addUser
Code extract:
#Override
protected User addUser(long companyId, LDAPUser ldapUser, String password)
throws Exception {
if (_log.isDebugEnabled()) {
_log.debug("Adding user " + ldapUser.getEmailAddress());
}
boolean autoPassword = ldapUser.isAutoPassword();
if (!PropsValues.LDAP_IMPORT_USER_PASSWORD_ENABLED) {
autoPassword = PropsValues.LDAP_IMPORT_USER_PASSWORD_AUTOGENERATED
&& !PropsValues.AUTH_PIPELINE_ENABLE_LIFERAY_CHECK;
if (!autoPassword) {
String defaultPassword = PropsValues.LDAP_IMPORT_USER_PASSWORD_DEFAULT;
if (StringUtil.equalsIgnoreCase(defaultPassword,
_USER_PASSWORD_SCREEN_NAME)) {
defaultPassword = ldapUser.getScreenName();
}
password = defaultPassword;
}
}
Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
birthdayCal.setTime(ldapUser.getBirthday());
int birthdayMonth = birthdayCal.get(Calendar.MONTH);
int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
int birthdayYear = birthdayCal.get(Calendar.YEAR);
User user = UserLocalServiceUtil.addUser(ldapUser.getCreatorUserId(),
companyId, autoPassword, password, password,
ldapUser.isAutoScreenName(), ldapUser.getScreenName(),
ldapUser.getEmailAddress(), 0, StringPool.BLANK,
ldapUser.getLocale(), ldapUser.getFirstName(),
ldapUser.getMiddleName(), ldapUser.getLastName(), 0, 0,
ldapUser.isMale(), birthdayMonth, birthdayDay, birthdayYear,
StringPool.BLANK, ldapUser.getGroupIds(),
ldapUser.getOrganizationIds(), ldapUser.getRoleIds(),
ldapUser.getUserGroupIds(), ldapUser.isSendEmail(),
ldapUser.getServiceContext());
_log.info("-----------------------------------------User||||Added----------------------------------------");
if (ldapUser.isUpdatePortrait()) {
byte[] portraitBytes = ldapUser.getPortraitBytes();
if (ArrayUtil.isNotEmpty(portraitBytes)) {
user = UserLocalServiceUtil.updatePortrait(user.getUserId(),
portraitBytes);
}
}
return user;
}
Created folder name META-INF in docroot/WEB-INF/ext-impl/src
In META-INF created a file named ext-spring.xml with the following code:
build and published my plugin
copied the customLdap-ext.war file from dist folder and pasted it in my Tomcat deploy folder
started my server the old configuration are loaded no log is printed while a new user is imported from ldap
Where am I going wrong in doing this?
Note: I am using liferay 6.2.0.1 CE-GA6
I have also overriden PortalLDAPImporterImpl.java. You don't have to define ext-spring.xml. Just take the original class, copy it to docroot/WEB-INF/ext-impl/src in package com.liferay.portal.security.ldap and change it. Do not create CustomPortalLDAPImporterImpl.java
Something in your description doesn't sound right - specifically the combination of an ext-plugin and
build and pusblished my plugin
copied the customLdap-ext.war file from dist folder and pasted it in my tomcat delpoy folder
While this is documented as the steps to deploy in production, you'll at least need to restart Liferay (ext is not hot-deployable).
Also, validate that the WAR file doesn't end up as a separate webapplication in tomcat. Instead it will be woven into Liferay, aka the ROOT web application. This is another thing that you can/should validate. And observe the documented steps for redeployment (different from first deployment), where you basically need to reinstall Liferay from scratch and your ext plugins.
I haven't validated if you can go without ext here, the documented steps are a prime reason to try to go without ext whenever possible.
If you follow Klimiuk's advice in the other answer to this question, note that you're depending on classloader order in that case: Some JVMs/appservers will pick up your implementation first, while others pick up the original one first. It's typically reproducible - e.g. if it works once, it'll always work. At least until an update to your environment changes the behavior any you suddenly wonder why your modification doesn't work any more (if you're lucky to find out quickly).

Programmatically list open projects in an eclipse workspace from outside of eclipse

I want to write a Gradle plugin which can inspect an eclipse workspace directory and iterate over the open projects within the workspace and determine the location of each.
Something like
Workspace workspace = EclipseUtils.parseWorkspace("c:/myEclipseWorkspace");
Collection<Project> projects = workspace.getProjects();
for (Project project : projects) {
System.out.println(String.format("name=%s, location=%s, open=%s",
project.getName(), project.getLocation(), project.isOpen()));
}
I've looked at my workspace and can see some .location files under c:\myEclipseWorkspace\.metadata\.plugins\org.eclipse.core.resources\.projects\
But these files are a custom binary format
Is there an eclipse API that I can invoke to parse these? Or some other solution to iterate the open projects in a workspace.
Please note that I want to do this externally to eclipse and NOT within an eclipse plugin.
Reading the Private Description to Obtain Location
Since you are writing in Java, then reuse the Eclipse code from your external location.
i.e. Pull out some of the key code from org.eclipse.core.resources.ResourcesPlugin. Start with the impl of org.eclipse.core.resources.ResourcesPlugin.getWorkspace() and then work your way to org.eclipse.core.resources.IWorkspaceRoot.getProjects()
The above code reads the project description here: org.eclipse.core.internal.resources.LocalMetaArea.readPrivateDescription(IProject, ProjectDescription) and that is called from org.eclipse.core.internal.localstore.FileSystemResourceManager.read(IProject, boolean) which has some logic about default locations.
This is the joy of EPL, as long as your new program/feature is EPL you can reuse Eclipse's core code to do new and wonderful things.
Reading Workspace State to Obtain Open/Close State
When reading workspace state, you are moving into the ElementTree data structures. Reading this without using the ElementTree classes is probably unrealistic. Using the ElementTree classes without full OSGi is probably unrealistic. I provide the following notes to help you on your way.
Working backwards:
ICoreConstants.M_OPEN is the flag value indicating project is open or closed (set for open, clear for closed)
M_OPEN is tested when Project.isOpen() is called
The flags at runtime are in ResourceInfo.flags
The flags are loaded by ResourceInfo.readFrom() called from SaveManager.readElement()
The DataInput input passed to readElement is from the Element Tree stored in the workspace meta directory in .metadata/.plugins/org.eclipse.core.resources/.root/<id>.tree. The specific version (id) of the file to use is recorded in the safe table .metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
The safe table is part of the SaveManager's internal state stored in a MasterTable
I've managed to parse the file using this as a reference
protected Location parseLocation(File locationFile) throws IOException {
String name = locationFile.getParentFile().getName();
DataInputStream in = new DataInputStream(new FileInputStream(locationFile));
try {
in.skip(ILocalStoreConstants.BEGIN_CHUNK.length);
String path = in.readUTF();
int numRefs = in.readInt();
String[] refNames = new String[numRefs];
for (int i = 0; i < numRefs; ++ i) {
refNames[i] = in.readUTF();
}
in.skipBytes(ILocalStoreConstants.END_CHUNK.length);
return new Location(name, path, refNames);
} finally {
in.close();
}
}
Unfortunately this doesn't seem to be able to detect if a project is closed or not. Any pointers on getting the closed flag would be much appreciated

How do I programmatically change the Eclipse CDT tool settings for a file?

I want to programmatically (from a plugin) change the "Other flags" field in the Miscellaneous settings in the Tool Settings tab for an individual file in a CDT managed build project. (See this Eclipse documentation page for a screenshot and brief description of how this change would be made using the UI.)
Note: I've updated this twice now as I approach a solution. But instead of adding an update onto the end (as I do for shorter questions), I'm revising the entire question. If it helps to see the breadcrumbs leading to where I am now, you can read the history.
The following code will result in settings written to the .cproject file (I'll go into detail on that below), but when I open the Properties dialog for the file, and click on C/C++ Build->Settings and then Miscellaneous, the changes do not appear in the "Other flags" field (as they do when I make changes using the dialog).
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow workbenchwindow = workbench.getActiveWorkbenchWindow();
IWorkbenchPage workbenchpage = workbenchwindow.getActivePage();
IEditorPart editorpart = workbenchpage.getActiveEditor();
IEditorInput editorinput = editorpart.getEditorInput();
IResource file = ((IFileEditorInput)editorinput).getFile();
IProject project = file.getProject();
IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(project);
IConfiguration[] configurations = buildInfo.getManagedProject().getConfigurations();
IConfiguration conf = configurations[0];
IFileInfo fileInfo = conf.createFileInfo(file.getFullPath());
ITool[] tools = fileInfo.getTools();
ITool tool = tools[0];
IOption option = tool.getOptionById("my.gnu.compiler.misc.other");
String oldOptionValue = option.getDefaultValue().toString();
String newOptionValue = oldOptionValue + " -eg";
ManagedBuildManager.setOption(fileInfo, tool, option, newOptionValue);
ManagedBuildManager.saveBuildInfo(project, true);
I looked at the differences between the .cproject file where I changed the tool settings manually, and in a different .cproject file after running the above code. Below are the pertinent bits from each.
Here is the XML from the .cproject file where the tool settings were changed manually:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.company.product.toolchain.configuration.changed.1964078554">
...
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" cleanCommand="rm -f" description="" id="com.company.product.toolchain.configuration.changed.1964078554" name="changed" parent="com.company.product.toolchain.configuration.changed">
...
<fileInfo id="com.company.product.toolchain.configuration.changed.1964078554.915152327" name="code.cpp" rcbsApplicability="disable" resourcePath="src/code.cpp" toolsToInvoke="com.company.product.toolchain.compiler.1643348654.1411455203">
<tool id="com.company.product.toolchain.compiler.1643348654.1411455203" name="Company GNU compilers" superClass="com.company.product.toolchain.compiler.1643348654">
<option id="company.gnu.compiler.misc.other.789167779" name="Other flags" superClass="company.gnu.compiler.misc.other" value="-c -fmessage-length=0 -eg" valueType="string"/>
<inputType id="com.company.product.toolchain.cxxinputtype.877052163" name="C++ Input" superClass="com.company.product.toolchain.cxxinputtype"/>
<inputType id="com.company.product.toolchain.cinputtype.1390394900" name="C input" superClass="com.company.product.toolchain.cinputtype"/>
</tool>
</fileInfo>
...
And here is the XML from the .cproject file where they were changed programmatically:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.company.product.toolchain.configuration.changed.2057644715">
...
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" cleanCommand="rm -f" description="" id="com.company.product.toolchain.configuration.changed.2057644715" name="changed" parent="com.company.product.toolchain.configuration.changed">
...
<fileInfo id="com.company.product.toolchain.configuration.changed.2057644715./test3/src/code.cpp" name="code.cpp" rcbsApplicability="disable" resourcePath="test3/src/code.cpp" toolsToInvoke="com.company.product.toolchain.compiler.1482360042.1005761865">
<tool id="com.company.product.toolchain.compiler.1482360042.1005761865" name="Company GNU compilers" superClass="com.company.product.toolchain.compiler.1482360042">
<option id="company.gnu.compiler.misc.other.999025984" superClass="company.gnu.compiler.misc.other" value="-c -fmessage-length=0 -eg" valueType="string"/>
<inputType id="com.company.product.toolchain.cxxinputtype.1253686787" name="C++ Input" superClass="com.company.product.toolchain.cxxinputtype"/>
<inputType id="com.company.product.toolchain.cinputtype.1141524787" name="C input" superClass="com.company.product.toolchain.cinputtype"/>
</tool>
</fileInfo>
...
Aside from the numbers, which I assume are some kind of GUIDs, there are three differences:
For some reason, the id attribute of the fileInfo element in the programmatic changes contains the path to the file, including the project name: id="com.company.product.toolchain.configuration.changed.2057644715./test3/src/code.cpp"
The resourcePath attribute value of the fileInfo element contains the project name, only in the programmatic changes: resourcePath="test3/src/code.cpp".
The option element in the fileInfo element as a name attribute (name="Other flags") that matches the field in the dialog, only in the manual changes.
I'm guessing that one or all of these differences are preventing my programmatic changes from being "compatible" with the manual ones (so they show up in the dialog). I'm trying to figure out how to create the IFileInfo, IOption (and ITool?) objects without causing these differences. I'm trying to find how these objects are created for the dialog, but haven't yet.
Any suggestions appreciated.
Update: I got an answer from Doug Schaefer to my question on the cdt-dev mailing list. He suggested I "stick breakpoints in places and see how the UI does it." I wrote back:
I have been doing that. I set a breakpoint in org.eclipse.cdt.managedbuilder.core.ManagedBuildManager.setOption(IResourceInfo, IHoldsOptions, IOption, String) and it triggers when I open the Properties dialog for a file, expand "C/C++ Build", select "Settings", and then "Miscellaneous" in the Tool Settings tab. I can see the arguments, and presumably if I can call setOption with the same arguments I'll get the same results in the .cproject file. But I haven't been able to figure out how to do that. Do you have any suggestions for how I figure out where those objects are created so I can set breakpoints there?
Update #2: Vladimir's answer solved my problem. While I was more concerned with difference number 3 in the two .cproject file fragments above, the key was difference 2 and the inclusion of the project name in difference 1.
I changed the code to create the IFileInfo object to:
IFileInfo fileInfo = conf.createFileInfo(file.getProjectRelativePath());
...which resulted in the fileInfo element not having the project name:
<fileInfo id="com.company.product.toolchain.configuration.changed.838214286.src/code.cpp" name="code.cpp" rcbsApplicability="disable" resourcePath="src/code.cpp" toolsToInvoke="com.company.product.toolchain.compiler.2027651356.1970239371">
...and most importantly, resulted in the programmatic changes showing up in the "Other flags" field in the Miscellaneous settings in the Tool Settings tab for the individual file. (I guess the other differences in the .cproject files are not important.)
I suspect there might be problem in you IFileInfo creation. Here's the code that we use to obtain IResourceInfo for a translation unit to set per-file options:
protected IResourceInfo getResourceInfo(ITranslationUnit translationUnit, ICProjectDescription prjDescription) {
ICProject cProject = translationUnit.getCProject();
if (cProject != null) {
ICConfigurationDescription cfgDescription = prjDescription.getActiveConfiguration();
IConfiguration configuration = ManagedBuildManager.getConfigurationForDescription(cfgDescription);
IPath projectPath = translationUnit.getResource().getProjectRelativePath();
IResourceInfo ri = configuration.getResourceInfo(projectPath, true);
if (ri == null) {
ri = configuration.createFileInfo(projectPath);
}
return ri;
}
return null;
}
Note this line, in particular:
IPath projectPath = translationUnit.getResource().getProjectRelativePath();
Maybe, all you need is to use getProjectRelativePath() in your code?
Generally you can set an option to different objects, i.e. a configuration (if you want the option to apply to all files of a given type in a configuration) or a resource (if you want the option to apply only to the files in a folder or to a single file).
setOption() has multiple prototypes; it looks like you used the one that applies to a file resource.
In my GNU ARM Eclipse Plug-in I successfully used another version:
setOption(IConfiguration config, IHoldsOptions holder, IOption option, String value)
You can see an example in this file, line 583.
I guess this will work in your case too.

Programmatically analyze java heap dump file

I want to write a program (preferably in java) that will parse and analyze a java heap dump file (created by jmap). I know there are many great tools that already do so (jhat, eclipse's MAT, and so on), but I want to analyze the heap from a specific perspective to my application.
Where can I read about the structure of the heap dump file, examples how to read it, and so on? Didn't find anything useful searching for it...
Many thanks.
The following was done with Eclipse Version: Luna Service Release 1 (4.4.1) and Eclipse Memory Analyzer Version 1.4.0
Programmatically Interfacing with the Java Heap Dump
Environment Setup
In eclipse, Help -> Install New Software -> install Eclipse Plug-in Development Environment
In eclipse, Window -> Preferences -> Plug-in Development -> Target Platform -> Add
Nothing -> Locations -> Add -> Installation
Name = MAT
Location = /path/to/MAT/installation/mat
Project Setup
File -> new -> Other -> Plug-in Project
Name: MAT Extension
Next
Disable Activator
Disable Contributions to the UI
Disable API analysis
Next
Disable template
Finish
Code Generation
Open plugin.xml
Dependencies -> Add
select org.eclipse.mat.api
Extensions -> Add
select org.eclipse.mat.report.query
right click on report.query -> New
Name: MyQuery
click "impl" to generate the class
Implementing IQuery
#CommandName("MyQuery") //for the command line interface
#Name("My Query") //display name for the GUI
#Category("Custom Queries") //list this Query will be put under in the GUI
#Help("This is my first query.") //help displayed
public class MyQuery implements IQuery
{
public MyQuery{}
#Argument //snapshot will be populated before the call to execute happens
public ISnapshot snapshot;
/*
* execute : only method overridden from IQuery
* Prints out "My first query." to the output file.
*/
#Override
public IResult execute(IProgressListener arg0) throws Exception
{
CharArrayWriter outWriter = new CharArrayWriter(100);
PrintWriter out = new PrintWriter(outWriter);
SnapshotInfo snapshotInfo = snapshot.getSnapshotInfo();
out.println("Used Heap Size: " + snapshotInfo.getUsedHeapSize());
out.println("My first query.")
return new TextResult(outWriter.toString(), false);
}
}
ctrl+shift+o will generate the correct "import" statements.
Custom queries can be accessed within the MAT GUI by accessing the toolbar's "Open Query Browser" at the top of the hprof file you have opened.
The ISnapshot interface
The most important interface one can use to extract data from a heap dump is ISnapshot. ISnapshot represents a heap dump and offers various methods for reading object and classes from it, getting the size of objects, etc…
To obtain an instance of ISnapshot one can use static methods on the SnapshotFactory class. However, this is only needed if the API is used to implement a tool independent of Memory Analyzer. If you are writing extensions to MAT, then your coding will get an instance corresponding to an already opened heap dump either by injection or as a method parameter.
Reference
Built in Command Line Utility
If you're looking to have a program generate the usual reports, there is a command line utility called ParseHeapDump available with any download of Eclipse's MAT tool. You'll be able to get useful html dumps of all the information MAT stores.
> ParseHeapDump <heap dump> org.eclipse.mat.api:suspects org.eclipse.mat.api:top_components org.eclipse.mat.api:overview #will dump out all general reports available through MAT
Hopefully this is enough information to get you started.
I'm not familiar with jhat, but Eclipse's MAT is open source. Their SVN link is available, perhaps you could look through that for their parser, perhaps even use it.

Categories