How can I use the eclipse indenter from my code? - java

I noticed the eclipse indenter has support for the latest version of java, and it would be nice if I could use that class to indent generated java source code. Is there a way of integrating it ?
EDIT: I need to be able to include the code formatter in my code. No external calls.
EDIT2: I've managed to get it working. You can read the story here. Thanks VonC !

You can try running the formatter as a standalone application (also detailed here).
eclipse -vm <path to virtual machine> -application org.eclipse.jdt.core.JavaCodeFormatter [ OPTIONS ] <files>
Try first to define formatting settings with eclipse IDE in order to achieve the right result, then export those settings, and use that configuration file in the eclipse.exe parameters.
Or see also "Generating a Config File for the Formatter Application"
eclipse [...] -config <myExportedSettings>
In a java program, you can try to directly format by:
Creating an instance of CodeFormatter
Using the method void format(aString) on this instance to format aString. It will return the formatted string.
Thanks to Geo himself and his report in his blog entry, I now know you need to use DefaultCodeFormatter
String code = "public class geo{public static void main(String[] args){System.out.println(\"geo\");}}";
CodeFormatter cf = new DefaultCodeFormatter();
TextEdit te = cf.format(CodeFormatter.K_UNKNOWN, code, 0,code.length(),0,null);
IDocument dc = new Document(code);
try {
te.apply(dc);
System.out.println(dc.get());
} catch (MalformedTreeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Again, full details in the blog entry. Thank you Geo for that feedback!
Thorbjørn Ravn Andersen mentions in the comments:
Maven2 Java Formatter Plugin v0.4 describes a maven plugin that allows Maven to invoke the Eclipse formatter.
As of 0.4 it invokes Eclipse 3.5 which does not support Java 8.

Actually, there is one problem with VonC's answer: DefaultCodeFormatter is in an 'internal' package, and therefore should not be be used by clients!
I recently asked the same question here on stackoverflow, and came up with the answer a little while later.
In short, you need to use ToolFactory, as in
ToolFactory.createCodeFormatter(null);

I was using the CodeFormatter in an Eclipse-independent project. The default options used by calling ToolFactory.createCodeFormatter(null); could not handle the source code - the result of the format() call being null.
A minimal working options setup is the following:
Hashtable<String, String> options = new Hashtable<>();
options.put("org.eclipse.jdt.core.compiler.codegen.targetPlatform", "1.8");
options.put("org.eclipse.jdt.core.compiler.compliance", "1.8");
options.put("org.eclipse.jdt.core.compiler.source", "1.8");
CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(options);

Related

Java: FileOutputStream("NUL:") not working after Java upgrade

On Windows, NUL is the null output device similar to /dev/null on Linux.
With Oracle Java 8 Update 331, trying to get a new FileOutputStream("NUL:") throws an exception. Previously (Java 8u321) it worked fine.
The problem seems to be the colon:
new FileOutputStream("NUL") - OK
new FileOutputStream("NUL:") - exception
Can anyone point me to docs or JDK sources regarding this change? I can't change the code itself because it is in a 3rd party lib (xnio-api).
try
{
new FileOutputStream("NUL:");
System.out.println("OK");
}
catch (FileNotFoundException e)
{
System.out.println(e);
}
I suspect this is the offending change.
Apparently it tries to avoid accessing ADS (alternate data streams), but seems to "accidentally" also prevent access to device-files like this.
If that's correct, then you can try setting the system property jdk.io.File.enableADS to true to re-enable the old behaviour.

How to enable a bukkit plugin first?

I have an interesting problem where I want to enable a specific Bukkit plugin first before any other plugins are enabled. This has proven a difficult task. I can't use the plugin.yml dependancy options because those assume I know what plugins are installed on any given server. I don't care if it doesn't load first, but I do need it to enable first.
I have tried several methods to accomplish this but with no luck:
Attempt 1:
static{
try {
Bukkit.getPluginManager().loadPlugin(plug);
Bukkit.getPluginManager().enablePlugin(plugin);
} catch (UnknownDependencyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidPluginException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidDescriptionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Allow me to explain. The static seems to run before most anything, including plugin loadups. This means I also have to define when it loads as well. This normally wouldn't be a problem, except non static API like getDataFolder() for the file Path doesn't work.
public static File plug = new File("/plugins/Debugger");
So unless I'm doing my Paths wrong, I have no clue why this throws an Exception.
NOTE: Yes, I have tried multiple different paths such as "plugins/Debugger" or "Debugger.jar" and ECT.
Method 2:
public void onLoad(){
Bukkit.getPluginManager().enablePlugin(plugin);
console.info("[Debugger] loaded first!");
}
This seemed too good to be true and this method actually seemed to get me closer to solving my problem. This Method is called whenever the plugin loads, so by enabling the plugin within the onLoad Method, it actually caused the plugin to enable first; But there were issues when loading:
[00:15:08] [Server thread/ERROR]: null initializing Debugger v1.0.0 (Is it up to date?)
java.lang.NullPointerException
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:396) ~[craftbukkit.jar:git-Bukkit-0ebb9c7]
at me.doublehelix457.Debugger.Debugger.onLoad(Debugger.java:20) ~[?:?]
at org.bukkit.craftbukkit.v1_10_R1.CraftServer.loadPlugins(CraftServer.java:299) [craftbukkit.jar:git-Bukkit-0ebb9c7]
at org.bukkit.craftbukkit.v1_10_R1.CraftServer.reload(CraftServer.java:723) [craftbukkit.jar:git-Bukkit-0ebb9c7]
at org.bukkit.Bukkit.reload(Bukkit.java:548) [craftbukkit.jar:git-Bukkit-0ebb9c7]
at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:25) [craftbukkit.jar:git-Bukkit-0ebb9c7]
Somehow despite the weird null initializing Debugger (Debugger is the test plugin name) the plugin still managed to enable first?
So the line it is referring to is Bukkit.getPluginManager().enablePlugin(plugin);
Doing some research online I noticed certain API like getServer() was not working within that Method and I believe that maybe this means that Bukkit or PluginManager may not exist yet.
If that's the case, then is there a workaround to this?
That said, I'm willing to take improvements on my current attempts or even try new ones, whatever gets the job done. Please do not ask "Why do you need to enable the plugin first?" I should mention that this version of bukkit is on 1.10.
Any HELPFUL advice would be much appreciated.
So now I feel really stupid. Turns out all I had to do was make my
plugin variable non-static and define it. All that trouble just to change
public static Debugger plugin; to public Debugger plugin = this;
This change works with Method 2.
Well. I hope that this benefits someone as to how they can enable a plugin first.

Sqoop, export HDFS to MySQL in Java

I'm trying to export from HDFS into MySql and have only been able to find the following technique:
public static boolean exportHDFSToSQL() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
try {
SqoopOptions options = new SqoopOptions();
options.setConnectString("jdbc:mysql://localhost:3306/dbName");
options.setUsername("user_name");
options.setPassword("pwd");
options.setExportDir("path of file to be exported from hdfs");
options.setTableName("table_name");
options.setInputFieldsTerminatedBy(',');
options.setNumMappers(1);
new ExportTool().run(options);
} catch (Exception e) {
return false;
}
return true;
}
The problem I have is with the ExportTool().run() method. I am using Sqoop 1.4.2 and this method has apparently been deprecated. Wanting to know the new way of achieving this? Or point me to a documented source that will assist.
Thanks
Sqoop currently do not exposes any Java API and thus such usage is not supported. It might work, however future versions might break this behavior.
I would expect that you see the deprecation because you are using ExportTool class from package com.cloudera.sqoop.tool, whereas the functionality was moved to package org.apache.sqoop.tool and the original instance was left there for backward compatibility. You can learn more about the namespace migration on appropriate Sqoop wiki page.

Is there any Eclipse refactoring API that I can call programmatically?

I need to refactor code in a wide term. I know that from inside the Eclipse IDE I can refactor my classes. But is there any API that I can use in a java project so that I can refactor projects dynamically through code?
I need some idea on how to achieve the following: a program that calls all the Eclipse refactorings for renaming and moving in a loop to refactoring the entire project in one shot!
I don't want to introduce new refactoring types by extending the refactoring classes. I just want to call them programmatically.
Something like this?
Anyone who supports a programming language in an Eclipse-based IDE
will be asked sooner or later to offer automated refactorings -
similar to what is provided by the Java Development Tools (JDT). Since
the release of Eclipse 3.1, at least part of this task (which is by no
means simple) is supported by a language neutral API: the Language
Toolkit (LTK). But how is this API used?
EDIT:
If you want to programmatically run refactorings without using the UI, RefactoringDescriptors (see article) can be used to fill in the parameters and execute the refactoring programmatically. If you create a plugin that depends on org.eclipse.core.runtime and add the org.eclipse.core.runtime.applications extension, you will be able to run an IApplication class from eclipse similar to a main(String[]) class in plain java apps. An example of calling the API can be found on the post.
ICompilationUnit cu = ... // an ICompilationUnit to rename
RefactoringContribution contribution =
RefactoringCore.getRefactoringContribution(IJavaRefactorings .RENAME_COMPILATION_UNIT);
RenameJavaElementDescriptor descriptor =
(RenameJavaElementDescriptor) contribution.createDescriptor();
descriptor.setProject(cu.getResource().getProject().getName( ));
descriptor.setNewName("NewClass"); // new name for a Class
descriptor.setJavaElement(cu);
RefactoringStatus status = new RefactoringStatus();
try {
Refactoring refactoring = descriptor.createRefactoring(status);
IProgressMonitor monitor = new NullProgressMonitor();
refactoring.checkInitialConditions(monitor);
refactoring.checkFinalConditions(monitor);
Change change = refactoring.createChange(monitor);
change.perform(monitor);
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
If you have more detailed questions about using the JDT APIs (AST, Refactoring, etc) I'd suggest you ask on the JDT Forum.
The answer below is great, but I answered with a wider perspective for the people who need a more bulky and tasty crunch of this wonderful cake:
RefactoringStatus status = new RefactoringStatus();
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkspaceRoot root = workspace.getRoot();
IProject[] projects = root.getProjects();
then:
for (ICompilationUnit unit : mypackage.getCompilationUnits()) {
IType primary = unit.findPrimaryType();
IMethod[] methods = primary.getMethods();
int i = 1;
for (IMethod method : methods) {
if (method.isConstructor()) {
continue;
}
makeChangetoMethods(status, method,"changedMethodVersion_" + i);
++i;
}
}
After that:
IProgressMonitor monitor = new NullProgressMonitor();
status = new RefactoringStatus();
Refactoring refactoring = performMethodsRefactoring(status, methodToRename, newName);
then:
Change change = refactoring.createChange(monitor);
change.perform(monitor);
find below the code for setting the descriptor:
String id = IJavaRefactorings.RENAME_METHOD;
RefactoringContribution contrib = RefactoringCore.getRefactoringContribution(id);
RenameJavaElementDescriptor desc = contrib.createDescriptor();
desc.setUpdateReferences(true);
desc.setJavaElement(methodToRename);
desc.setNewName(newName);
desc.createRefactoring(status);

JasperReports: filling a report throws an exception "Class not found when loading object from file"

I'm using the latest JDK and JasperReports. The reports are designed and compiled with iReport (4.02). Compiled reports are deployed to Eclipse project which is integrated with a Tomcat installation on Windows.
The problem is that calling JasperFillManager.fillReport(String sourceFileName, Map params, Connection connection), with correct parameters in place, will cause an exception with a message "net.sf.jasperreports.engine.JRException: Class not found when loading object from file".
I've debugged the code and all parameters have valid values. Also the reports work fine when previewed in iReport. I've copied all jar files from the Jasper project lib dir to my Web App Libraries.
The code is divided in multiple places in the actual code but the significant parts are below:
JasperPrint print = JasperFillManager.fillReport(templatePath, params, conn);
byte[] output = null;
try {
output = JasperExportManager.exportReportToPdf(print);
} catch (JRException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return output;
Problem solved.
The issue was caused by iReport Designer. I had defined some color formatting by selecting from available predefined color list instead of the the color wheel. This cause the reports to use variables from NetBeans jars instead of using color values.
I used jasperreports-6.17.0.jar and the issue is solved. Old versions created issue.

Categories