How do I avoid a PMD CloseResource violation? - pmd

I'm modifying my application code in order to respect the pmd rules. I had a Close Resource error in this code:
Connection c = DataSourceUtils.getConnection(dataSource);
Statement request = null;
try {
request = c.createStatement();
request.execute(loadDataRequest);
} catch (SQLException e) {
dataLogger.error(e);
throw e;
}
So I searched and found an apache utility for avoiding it: DButils
My code became like this
Connection c = DataSourceUtils.getConnection(dataSource);
Statement request = null;
try {
request = c.createStatement();
request.execute(loadDataRequest);
} catch (SQLException e) {
dataLogger.error(e);
throw e;
} finally {
DbUtils.closeQuietly(request);
DbUtils.closeQuietly(c);
}
However, I'm still having the PMD alert in eclipse and sonar reports! Do you have any idea how to fix that permanently?

You can set the closeTargets property of the CloseResource PMD rule. When PMD finds similar method names as in the closeTargets property, it won't fire the warning message:
<properties>
<property name="types" value="Connection,Statement,ResultSet"/>
<property name="closeTargets" value="closeQuietly, closeConnection, close"/>
</properties>
Alternatively, you can use SourceMeter, which includes this configuration natively.

The problem is that PMD doesn't know closeQuietly() closes the connection. And it isn't that smart because if your method was named close() you'd have the same problem. And since it is a Java rule, it isn't easy to change the implementation because then you'd have to repackage the Eclipse and Sonar PMD plugins to recognize your copy of the rule.
Your options:
1) Add //NOPMD comment to suppress
2) Refactor the code to get/close the connection in a superclass so you only have it once.

PMD defines a parameter for this rule called closeTargets. By default, this parameter is set to close method. You can change it for specifying DbUtils.closeQuietly

Related

Eclipse pre-commit hook to execute arbitrary logic

Does eclipse support pre-commit checks for executing logic in a script or java class? Specifically, I need logic to search the source file for println, TODO, etc., statements before committing to SVN.
If you program, you know what I'm talking about... :-)
public void submitOrder(Order order){
if(order.valid()){
println("hi!")
orderProcessor.validatePayment(order)
println("hi2")
...
}else{
println("logging to journal...") //TODO remove this later
journal.log(INVALID_ORDER, order)
println("after journal")
println("really throwing exception now!")
throw new InvalidOrderException(order)
}
}

How to get resource from another plugin?

I have 2 plugins A and B. In the MANIFEST.MF of the A I do have plugin B in a Require-Bundle section. But when I try to get B's resource from A like
ClassFromA.class.getClassLoader().getResource('resource_from_B')
I am getting null. If I put B's resourŅe (folder) to A's root everything works like a charm. Am I missing something?
NOTE: I read Lars Vogel's article
Bundle bundle = Platform.getBundle("de.vogella.example.readfile");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try {
file = new File(FileLocator.resolve(fileURL).toURI());
} catch (URISyntaxException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
^this solution works when I run my plugin from eclipse, but when I pack it to jar and try to install from the local update site I'm getting
java.lang.IllegalArgumentException: URI is not hierarchical
P.S. I have also read several relative questions on the StackOverflow but wasn't able to find the answer:
Java Jar file: use resource errors: URI is not hierarchical
Why is my URI not hierarchical?
SOLUTION:
Many thanks to #greg-449. So the correct code is:
Bundle bundle = Platform.getBundle("resource_from_some_plugin");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try {
URL resolvedFileURL = FileLocator.toFileURL(fileURL);
// We need to use the 3-arg constructor of URI in order to properly escape file system chars
URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null);
File file = new File(resolvedURI);
} catch (URISyntaxException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
NOTE: also it's very important to use the 3-arg constructor of URI in order to properly escape file system chars.
Use
FileLocator.toFileURL(fileURL)
rather than FileLocator.resolve(fileURL) when you want to use the URL with File.
When the plugin is packed into a jar this will cause Eclipse to create an unpacked version in a temporary location so that the object can be accessed using File.
Why not use Bundle.getResource? That seems to be the OSGi way to access resources.
Your first attempt might work if you use a ClassFromB.class.getClassLoader instead of A.

Suppress Errors in JavaScript validation

I'm currently developing an eclipse plugin. This plugin contains a project nature which depends on the javaScript nature of jsdt.
Now at a few details the JavaScripts that the projects of my nature can contain are somewhat special.
They can contain "compiler hints" which are basicly statements beginning with #
They can contain return statements outside of functions
But at this two points the standard validation of jsdt come in and marks them as errors (which is normally right). I already managed to get this errors filtered out in the properties of the JavaScript validator (manually).
My question is, how can i exclude these errors from the validation of jsdt automatically for the projects with my nature?
JSDT uses concrete syntax parser which generates syntax errors.
You can't disable this. Only semantics error or warnings can be configured.
However you can disable entire validation of JSDT.
Below solution will suppress errors ands warnings which are generated while we save some changes on java script files. (Auto Build, Build)
Open Properties Dialog of Your Project.
Choose Builders item.
Uncheck "JavaScript Validator". And Press OK button.
Remove current errors and warnings from Problems View
This solution can't eliminate error or warning annotations in editor while you edit. They will show up on editor temporarily only when you edit it.
After a lot of research, hours of deleting markers and debugging i finally managed to delete the errors i wanted. In a bad bad way of course but i've come to a point where i just wanted this to work no matter how it's done.
If you ever want to delete existing problems that had been created during the validation process of jsdt you need to do the following (and you must not ommit anything):
Create a class extending org.eclipse.wst.jsdt.core.compiler.ValidationParticipant
Override isActive(), buildStarting() and reconcile() methods.
So there are two things you basicly have to care about.
The actual problem markers that will be created or had already been created at the end of the validation process.
The Problems created by the validation process. They are of the type CategorizedProblem and can be obtained by the ReconcileContext object that is passed to the reconcile() method.
It seems to me that the CategorizedProblems will be translated to problem markers after the validation process.
So what you need to do is:
Delete all unwanted problem markers of all files in buildStarting (this removes problem markers from all files in your project that are about to be validated)
Iterate the CategorizedProblem objects of the ReconcileContext (getProblems())
Create a new Array containing only the CategorizedProblems you want to keep
Set this new Array to the ReconcileContext with putProblems()
Delete the unwanted markers again for that file (i don't know why this is needed, please don't ask, i don't care anymore :-/)
An example implementation of such a validationParticipant could look like this: (this one will filter out problems complaining about return statements outside of methods:
[...ommited imports ...]
public class MyValidationParticipant extends org.eclipse.wst.jsdt.core.compiler.ValidationParticipant{
#Override
public boolean isActive(IJavaScriptProject project) {
return true;
}
#Override
public void buildStarting(BuildContext[] files, boolean isBatch) {
super.buildStarting(files, isBatch);
for(BuildContext context : files){
IFile file = context.getFile();
deleteUnwantedMarkers(file);
}
}
#Override
public void reconcile(ReconcileContext context) {
IResource resource = context.getWorkingCopy().getResource();
CategorizedProblem[] newProblems = new CategorizedProblem[0];
ArrayList<CategorizedProblem> newProblemList = new ArrayList<CategorizedProblem>();
CategorizedProblem[] probs = context.getProblems("org.eclipse.wst.jsdt.core.problem");
if(probs != null){
for(CategorizedProblem p : probs){
if(!(p.getMessage().equals("Cannot return from outside a function or method."))){
newProblemList.add(p);
}
}
}
}
context.putProblems("org.eclipse.wst.jsdt.core.problem", newProblemList.toArray(newProblems));
deleteUnwantedMarkers(resource);
}
public static void deleteUnwantedMarkers(IResource resource){
if(resource.isSynchronized(IResource.DEPTH_INFINITE)){
try {
IMarker[] markers = resource.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
if(markers != null && markers.length > 0){
for(IMarker m : markers){
Object message = m.getAttribute(IMarker.MESSAGE);
if(message.equals("Cannot return from outside a function or method.")){
m.delete();
}
}
}
}catch (CoreException e) {
e.printStackTrace();
}
}
}
}
As i said, this is kind of a bad solution since the code relies on the String of the error message. There should be better ways to identify the problems you don't want to have.
Don't forget to add a proper extension in your plugin.xml for the ValidationParticipant.

GWT Product Mode AssertionException Catch ? HOW?

in product mode in GWT the assertion is not available which is good, but because of a GXT error I get an assertion error and because the necessary classes are not available all I get is a com.google.gwt.core.client.JavaScriptException error in the browser and it's not enough to properly debug it. The reason why I need this is because in my custom framework I created a class that's responsible for error handling
GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void onUncaughtException(Throwable e) {
addError(e);
}
});
public void addError(Throwable ex)
{
if(!ex.getClass().equals(AssertionError.class))//(ex instanceof AssertionError))
{
this.addError(ex, true);
}
}
as you can see I've tried to capture the error but I'm unable to in production mode. I somehow need to be able to sepcify the exception so I can filter it. All errors get into the logs and I don't want these errors to appear there
GXT Error => http://www.sencha.com/forum/showthread.php?171409-RowEditor-AssertionError&p=709005
thanks help
By Egg
You need to enable assertions in your compiled code, and this is done very similarly to how you would do this in a standard jvm, using the -ea flag. Instead of passing this to the jvm though, it needs to be passed to the Compiler class (or put in the program args if running from eclipse, or some other tool).
See http://code.google.com/webtoolkit/doc/latest/DevGuideCompilingAndDebugging.html#DevGuideCompilerOptions for the list of all args you can pass to the compiler

JAXB in Netbeans Module

Their Seems to be a problem when i attempt to run JAXB marshaller in a netbeans module. Originally I thought it was the node implimentation so i spent a couple of days reorganizing everything however I was still recieveing the odd error message
javax.xml.bind.JAXBException: ClassCastException: attempting to cast jar:file:/C:/Program%20Files/jmonkeyplatform/ide/modules/ext/jaxb/api/jaxb-api.jar!/javax/xml/bind/JAXBContext.class to jar:file:/C:/Program%20Files/Java/jdk1.6.0_21/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class. Please make sure that you are specifying the proper ClassLoader.
at javax.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:96)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:205)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
at com.spectre.util.JAXBImporterExporter.write(JAXBImporterExporter.java:63)
I am not exactly sure what the issue is the importer/exporter seems to work in normal projects and the importer seems to work fine when parsing the file however the export seems to cause issues. The method I use to export is
public static <T> void write(T savable, Class<T> type,Object path) {
try {
JAXBContext jc = JAXBContext.newInstance(type);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
if(path instanceof File)
marshaller.marshal(savable, (File)path);
else if(path instanceof OutputStream){
marshaller.marshal(savable, (OutputStream)path);
}else throw new NoSuchMethodException("The Field Path must be of either type File or OutputStream");
} catch (NoSuchMethodException ex) {
Exceptions.printStackTrace(ex);
} catch (JAXBException ex) {
Exceptions.printStackTrace(ex);
}
}
any assistance is appreciated
An easy solution is to add module dependency on org.netbeans.modules.xml.jaxb.api module that is part of NetBeans. This will avoid clash between two versions JAXB classes (one from JDK and second from that module that is preferred in runtime).
I Found that if you instead change the initialization of the JAXBContext to JAXBContext.newInstane(String contextPath,ClassLoader loader) in which the class loader you recieve from the current class your in ie MyClass.class.getClassLoader(). Also instead of a schema you can use a jaxb.index which is just a text file list of the class names that you've augmented for use with jaxb that is inside their same directory. Their should be one for each directory though for me they where all in the same directory. and seperated in the same string in the constructor's context path param with :
HERE