For some reason I need to rewrite groovy code to java. It's gradle plugin if it matters. But I don't understand some code. Could you please explain it step-by-step, probably with java code?
class DeployPlugin implements Plugin<Project> {
#Override
void apply(Project project) {
project.with {
apply plugin: 'org.hidetake.ssh'
ssh.settings {
identity = file(ssh_file)
knownHosts = allowAnyHosts
passphrase = ssh_passphrase
}
...
As far as I understand project.with{ } means methods (which?) inside are called for project instance.
apply plugin: 'org.hidetake.ssh' - can it be expressed with project.getPlugins() .apply("org.hidetake.ssh") ?
ssh.settings - what is ssh here? If it is a variable, how can I get it's instance in java?
ssh.settings {someExpressions} - what are curly braces used for in this context?
The code will probably look something like this in Java:
public class DeployPlugin implements Plugin<Project> {
#Override
public void apply(Project project) {
project.getPlugins().apply("org.hidetake.ssh");
org.hidetake.groovy.ssh.core.Service ssh = project.getExtensions().getByType(org.hidetake.groovy.ssh.core.Service.class);
ssh.settings(new MethodClosure(this, "configureSettingsClosure"));
}
private void configureSettingsClosure(org.hidetake.groovy.ssh.core.settings.GlobalSettings settings) {
settings.setIdentity(ssh_file);
settings.setKnownHosts(settings.getAllowAnyHosts());
settings.setPassphrase("p#ssw0rd");
}
or if you want to not depend on groovy-ssh probably something like this, but I'd not recommend it:
public class DeployPlugin implements Plugin<Project> {
#Override
public void apply(Project project) {
project.getPlugins().apply("org.hidetake.ssh");
Object ssh = project.getExtensions().getByName("ssh");
try {
Method settings = ssh.getClass().getDeclaredMethod("settings", Closure.class);
settings.invoke(ssh, new MethodClosure(this, "configureSettingsClosure"));
} catch (IllegalAccessException | NoSuchMethodException e) {
throw new AssertionError("Should not happen except by using a different groovy-ssh version that changed incompatibly", e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
private void configureSettingsClosure(Object settings) throws InvocationTargetException {
try {
Method setIdentity = settings.getClass().getDeclaredMethod("setIdentity", Object.class);
setIdentity.invoke(settings, ssh_file);
Method getAllowAnyHosts = settings.getClass().getDeclaredMethod("getAllowAnyHosts");
Method setKnownHosts = settings.getClass().getDeclaredMethod("setKnownHosts", File.class);
setKnownHosts.invoke(settings, getAllowAnyHosts.invoke(settings));
Method setPassphrase = settings.getClass().getDeclaredMethod("setPassphrase", String.class);
setPassphrase.invoke(settings, "p#ssw0rd");
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new AssertionError("Should not happen except by using a different groovy-ssh version that changed incompatibly", e);
}
}
Related
I'd like to use a MemberSubstitution to rewrite accesses to a particular field. For this I'd like to implement a Plugin to apply this change at compile time using the ByteBuddy Maven plug-in. How can I register the substitution in this case?
Update to give some more context:
Here's the class I'd like to modify:
public class Foo {
private final String FOO = "FOO!";
private final String BAR = "BAR!";
public String test() {
return FOO;
}
}
Here's my Plugin:
public class HookInstallingPlugin implements Plugin {
#Override
public boolean matches(TypeDescription target) {
return target.getName().equals("Foo");
}
#Override
public Builder<?> apply(Builder<?> builder, TypeDescription typeDescription, ClassFileLocator classFileLocator) {
Field f = null;
try {
f = Class.forName("com.example.foo.Foo").getDeclaredField("BAR");
} catch (NoSuchFieldException | SecurityException | ClassNotFoundException e) {
e.printStackTrace();
}
builder = builder.visit(MemberSubstitution.strict()
.field(ElementMatchers.named("FOO"))
.onRead()
.replaceWith(f)
.on(named("test")));
return builder;
}
#Override
public void close() throws IOException {
}
I'd expect test() to return "BAR!", but it actually returns "FOO!", and this is confirmed when examining the byte code using javap. The type isn't altered, but I can canform that the apply() method was run.
A plugin has two methods:
matches determines what types to instrument.
apply instruments thos types. It provides a DynamicType.Builder to register your changes.
A MemberSubstitution is a decorator, not a replacement for methods. Thus it is registered via the visit method on the DynamicType.Builder:
builder = builder.visit(MemberSubstitution.strict().field(...).onWrite().stub().on(...));
This would for example remove all field writes of matched fields in all methods within the supplied matcher in the last argument.
Assuming I have to read from a file, and then construct a java object out of it.
PersonData p = new PersonData();
p.setName(readTokenAsString());
p.setAge(AgeConverter.createFromDateOfBirth(readTokenAsString())); // this throws a checked exception if the date of birth is mal-formed.
//... a list of methods that throws exception as AgeConverter
Behavior I want: If one attribute has problem, just ignore it and keep process other attributes.
Solution I can think of:
try {
p.setAge1(...);
} catch (Exception e) {
//log and ignore
}
try {
p.setAge2(...);
} catch (Exception e) {
//log and ignore
}
//repeat for each attribute
Question:
Is there better way to do this to avoid repetition? Functional style maybe?
a) What's the best approach if I cannot modify PersonData class.
b) What's the best approach if I can rewrite PersonData class.
Given your current declaration, I would do it as follows.
Define a #FunctionalInterface to which you can pass your I/O logic:
#FunctionalInterface
public interface CheckedSupplier<T> {
T getValue() throws Exception;
}
Define an utility method that consumes the #FunctionaInterface:
public static final <T> T getValueWithDefault(CheckedSupplier<T> supplier, T defaultValue) {
try {
return supplier.getValue();
} catch (Exception e){
return defaultValue;
}
}
Use the utility method as follows:
PersonData p = new PersonData();
p.setName(getValueWithDefault(() -> readTokenAsString(), "default"));
p.setAge(getValueWithDefault(() -> AgeConverter.createFromDateOfBirth(readTokenAsString()), 0));
This should do the trick regardless of weather you want modify the PersonData class or not.
If you use Java 8 you can do something like this. Create your own functional interface with one method that throws Exception
public interface MyConsumer<T> {
public void process(T t) throws Exception;
}
And create a static method to use that interface
public static <T> void setAndLogException(T value, MyConsumer<T> consumer) {
try {
consumer.process(value);
} catch (Exception e) {
// log exception
}
}
And then using it like setAndLogException(AgeConverter.createFromDateOfBirth(readTokenAsString()), p::setAge);
You can also use solution provided by this: https://stackoverflow.com/a/28659553/6648303
This solution won't complain at compile phase about checked Exceptions.
It would be something like this:
public static void ignoringExc(RunnableExc r) {
try { r.run(); } catch (Exception e) { }
}
#FunctionalInterface public interface RunnableExc { void run() throws Exception; }
and then:
PersonData p = new PersonData();
ignoringExc(() -> p.setName(readTokenAsString()));
...
I'm building a GUI application in Java using an application framework (Netbeans Platform) which requires a large amount of nearly identical classes to implement extremely similar Action classes. I've spent a lot of time attempting to generate these actions programmatically. Although I'm able to generate the Actions, the framework utilizes annotations during compile time to generate other internal cache/data files which I've been unable to reproduce using a programmatic approach.
I'm wondering if code generation tools are a better solution, or perhaps some custom annotations which wrap the framework annotations. Perhaps something like Lombok, or maybe a maven plugin. But don't know where to start and am not sure if this is even a good path to explore. Ideally, I think it would be great to define the actions in a data file and generate the java code at compile time.
The project is open source, and a number of other actions are on github. Here is an example of what the template might look like, the pieces I would need to inject replaced with {{string}}, {{code}} and {{int}}:
// imports omitted
#ActionID(
category = {{string}},
id = {{string}})
#ActionRegistration(
iconBase = {{string}},
displayName = "resources.MessagesBundle#" + {{string}},
lazy = false)
#ActionReferences({
#ActionReference(
path = {{string}},
position = {{int}})
})
public final class {{string}} extends AbstractAction implements UGSEventListener {
public static final String ICON_BASE = {{string}};
private BackendAPI backend;
public SoftResetAction() {
this.backend = CentralLookup.getDefault().lookup(BackendAPI.class);
this.backend.addUGSEventListener(this);
putValue("iconBase", ICON_BASE);
putValue(SMALL_ICON, ImageUtilities.loadImageIcon(ICON_BASE, false));
putValue("menuText", {{string}});
putValue(NAME, {{string}});
}
#Override
public void UGSEvent(UGSEvent cse) {
java.awt.EventQueue.invokeLater(() -> setEnabled(isEnabled()));
}
#Override
public boolean isEnabled() {
{{code}}
}
#Override
public void actionPerformed(ActionEvent e) {
{{code}}
}
}
You should try a code generator like Telosys ( http://www.telosys.org/ )
This tool is designed for this kind of situation, you just have to create a template for each type of repetitive class and launch the generation.
For more information see the templating principles : http://www.telosys.org/templates.html
Everything is free and open source, so you can reuse existing templates and adapt them according to your needs.
Some interresting posts about this tool :
https://modeling-languages.com/telosys-tools-the-concept-of-lightweight-model-for-code-generation/
https://dzone.com/articles/telosys-a-code-generation-tool-by-laurent-guerin
You can design a public Action class for common using just like blow. This is only a section of sample code. If some modules has its own biz logical, you can implements this PubAction to any subclass.
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.AbstractAction;
public abstract class PubAction
extends AbstractAction
implements AppEventListener
{
protected ActionInterceptor interceptor;
protected IExceptionHandler exceptionHandler;
protected IActionStatusJudge actionStatusJudge = null;
public static final String TOOLBAR_SHOWNAME_KEY = "TOOLBAR_SHOWNAME_KEY";
public PubAction()
{
setShowNameInToolbar(false);
}
public String getBtnName() {
return (String)getValue("Name");
}
public void setBtnName(String btnName) {
putValue("Name", btnName);
}
public void setCode(String code)
{
putValue("Code", code);
}
public void handleEvent(AppEvent event)
{
updateStatus();
}
public void updateStatus()
{
boolean isEnable = isActionEnable();
setEnabled(getActionStatusJudge() == null ? isEnable : getActionStatusJudge().isActionEnable(this, isEnable));
}
protected boolean isActionEnable() {
return true;
}
public void setShowNameInToolbar(boolean isShow)
{
putValue("TOOLBAR_SHOWNAME_KEY", isShow ? Boolean.TRUE : Boolean.FALSE);
}
public void actionPerformed(ActionEvent e) {
Logger.debug("Entering " + getClass().toString() + ".actionPerformed");
beforeDoAction();
try
{
if ((interceptor == null) || (interceptor.beforeDoAction(this, e)))
{
try
{
doAction(e);
if (interceptor != null) {
interceptor.afterDoActionSuccessed(this, e);
}
} catch (Exception ex) {
if ((interceptor == null) || (interceptor.afterDoActionFailed(this, e, ex)))
{
if (getExceptionHandler() != null)
{
processExceptionHandler(ex);
}
else if ((ex instanceof RuntimeException))
{
throw ((RuntimeException)ex);
}
throw new RuntimeException(ex);
}
}
}
}
finally
{
Logger.debug("Leaving " + getClass().toString() + ".actionPerformed");
}
}
protected void processExceptionHandler(Exception ex)
{
new ExceptionHandlerUtil().processErrorMsg4SpecialAction(this, getExceptionHandler(), ex);
}
protected void beforeDoAction()
{
Method[] ms = getClass().getMethods();
for (Method m : ms)
{
Class<?> clazz = m.getReturnType();
if (AbstractUIAppModel.class.isAssignableFrom(clazz)) {
try
{
AbstractUIAppModel model = (AbstractUIAppModel)m.invoke(this, null);
if (model == null)
return;
LoginContext ctx = model.getContext();
if (ctx == null)
break;
ShowStatusBarMsgUtil.showStatusBarMsg("", ctx);
} catch (IllegalArgumentException e) {
Logger.debug(e.getMessage());
} catch (IllegalAccessException e) {
Logger.debug(e.getMessage());
} catch (InvocationTargetException e) {
Logger.debug(e.getMessage());
}
}
}
}
public abstract void doAction(ActionEvent paramActionEvent) throws Exception;
public ActionInterceptor getInterceptor()
{
return interceptor;
}
public void setInterceptor(ActionInterceptor interceptor) {
this.interceptor = interceptor;
}
public IExceptionHandler getExceptionHandler() {
return exceptionHandler;
}
public void setExceptionHandler(IExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
}
public IActionStatusJudge getActionStatusJudge() {
return actionStatusJudge;
}
public void setActionStatusJudge(IActionStatusJudge actionStatusJudge) {
this.actionStatusJudge = actionStatusJudge;
}
}
I'd like to see an example to prevent JaCoCo to report private empty constructors as non-covered code in a Java class.
In the maven plugin configuration I have
<rule>
<element>CLASS</element>
<excludes>
<exclude>JAVAC.SYNTHCLASS</exclude>
<exclude>JAVAC.SYNTHMETH</exclude>
</excludes>
</element>
</rule>
Isn't there something similar for the constructor?
This is not supported. The official documentation says:
Filters for Code where Test Execution is Questionable or Impossible by Design
Private, empty default constructors - assuming no calls to it
Plain getters and setters
Blocks that throw AssertionErrors - Entire block should be ignored if a condition (if !assertion throw new AssertionError)
see also : https://github.com/jacoco/jacoco/issues/298
Update: This was fixed in https://github.com/jacoco/jacoco/pull/529 and should be in 0.8.0.
There is no way to turn that option off. If you desperately need to meet some quality gate related to coverage you can always use a workaround and invoke these private constructors via reflection.
For this use case, reflection is perfectly acceptable, there are few and well known classes. The bellow code could be used with an automatic class detection based on the name. For sample ".*Factory" classes with additional asserts.
#Test
public void testCoverage()
throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
coverageSingleton(MySingleton1.class);
coverageSingleton(MySingleton2.class);
}
private <S> void coverageSingleton(Class<S> singletonClass)
throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
final Constructor<S> constructor = singletonClass.getDeclaredConstructor();
constructor.setAccessible(true);
constructor.newInstance();
}
As per official documentation, it's going to be released with 0.8.0
Filters for Code where Test Execution is Questionable or Impossible by
Design
Private empty constructors that do not have arguments - Done
You can find details here.
This is not solving the essential problem that empty private constructors should not need coverage, but to actually make JaCoCo report coverage on an empty private constructor you need to call it. How do you do that? You call it in the static initialization block.
public class MyClass {
static {
new MyClass();
}
private MyClass(){}
}
EDIT:
Turned out that there is no guarantee on the static initialization block to be executed. Thus we are limited to using methods as this one:
static <T> void callPrivateConstructorIfPresent(Class<T> clazz){
try{
Constructor<T> noArgsConstructor = clazz.getDeclaredConstructor();
if(!noArgsConstructor.isAccessible()){
noArgsConstructor.setAccessible(true);
try {
noArgsConstructor.newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{
e.printStackTrace();
}
noArgsConstructor.setAccessible(false);
}
} catch(NoSuchMethodException e){}
}
As 0.8.0 is not yet released, I created a hamcrest matcher that checks whether a class is an utility class and additionally calls the private constructor using reflection (for code coverage purpose only).
https://github.com/piotrpolak/android-http-server/blob/master/http/src/test/java/ro/polak/http/utilities/IOUtilitiesTest.java
package ro.polak.http.utilities;
import org.junit.Test;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static ro.polak.http.ExtraMarchers.utilityClass;
public class IOUtilitiesTest {
#Test
public void shouldNotBeInstantiable() {
assertThat(IOUtilities.class, is(utilityClass()));
}
}
https://github.com/piotrpolak/android-http-server/blob/master/http/src/test/java/ro/polak/http/ExtraMarchers.java
package ro.polak.http;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ExtraMarchers {
private static final UtilClassMatcher utilClassMatcher = new UtilClassMatcher();
public static Matcher<? super Class<?>> utilityClass() {
return utilClassMatcher;
}
private static class UtilClassMatcher extends TypeSafeMatcher<Class<?>> {
#Override
protected boolean matchesSafely(Class<?> clazz) {
boolean isUtilityClass = false;
try {
isUtilityClass = isUtilityClass(clazz);
} catch (ClassNotFoundException | InstantiationException e) {
// Swallowed
}
// This code will attempt to call empty constructor to generate code coverage
if (isUtilityClass) {
callPrivateConstructor(clazz);
}
return isUtilityClass;
}
#Override
protected void describeMismatchSafely(Class<?> clazz, Description mismatchDescription) {
if (clazz == null) {
super.describeMismatch(clazz, mismatchDescription);
} else {
mismatchDescription.appendText("The class " + clazz.getCanonicalName() + " is not an utility class.");
boolean isNonUtilityClass = true;
try {
isNonUtilityClass = !isUtilityClass(clazz);
} catch (ClassNotFoundException e) {
mismatchDescription.appendText(" The class is not found. " + e);
} catch (InstantiationException e) {
mismatchDescription.appendText(" The class can not be instantiated. " + e);
}
if (isNonUtilityClass) {
mismatchDescription.appendText(" The class should not be instantiable.");
}
}
}
#Override
public void describeTo(Description description) {
}
private void callPrivateConstructor(Class clazz) {
try {
Constructor<?> constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
constructor.newInstance();
} catch (NoSuchMethodException | IllegalAccessException |
InstantiationException | InvocationTargetException e) {
// Swallowed
}
}
private boolean isUtilityClass(Class clazz) throws ClassNotFoundException, InstantiationException {
boolean hasPrivateConstructor = false;
try {
clazz.newInstance();
} catch (IllegalAccessException e) {
hasPrivateConstructor = true;
}
return hasPrivateConstructor;
}
}
}
I cooked up a class ExceptionHandler<T extends Exception, OptionalReturnType> (see below) to eliminate some (what I view as) boilerplate code which was cluttering up actual implementation, while still providing a hook for explicit Exception handling if desired in the future. For the most part, in my application (essential a scientific computation), there is no such thing as recovery from exceptions - I need a log of the problem so I can fix it, but otherwise I'm just going to re-run once the problem is corrected.
Do other people do this (at least, in my specific application situation)? Is it dumb to do so (if yes, some explanation as to why would be nice)?
ExceptionHandler:
public abstract class ExceptionHandler<ExceptionType extends Exception,OptionalReturn> {
public abstract OptionalReturn handle(ExceptionType e);
//assorted boilerplate ExceptionHandling, e.g.:
public static <ET extends Exception> ExceptionHandler<ET, ?> swallower(final boolean printStackTrace, final String string) {
return new ExceptionHandler<ET,Object>() {
#Override public Object handle(ET e) {
if(printStackTrace) { e.printStackTrace(); }
if(string!=null && !string.isEmpty()) { System.err.println(string); }
return null;
}
};
}
public static <ET extends Exception> ExceptionHandler<ET, ?> swallower() { return swallower(false,null); }
}
example use (which I'm in the process of chopping down so I'm actually not writing quite so much):
public class Getter<From> implements Function<Future<? extends From>, From> {
private ExceptionHandler<InterruptedException,?> IEH;
private ExceptionHandler<ExecutionException,?> EEH;
public static final ExceptionHandler<InterruptedException,?> IEH_SWALLOWER = ExceptionHandler.swallower(true,"Returning null.");
public static final ExceptionHandler<ExecutionException,?> EEH_SWALLOWER = ExceptionHandler.swallower(true,"Returning null.");
private Getter() { this(IEH_SWALLOWER,EEH_SWALLOWER); }
private Getter(ExceptionHandler<InterruptedException,?> IEH, ExceptionHandler<ExecutionException,?> EEH) {
this.IEH = IEH;
this.EEH = EEH;
}
public static <T> Getter<T> make() { return new Getter<T>(); }
public static <T> Getter<T> make(ExceptionHandler<InterruptedException,?> IEH, ExceptionHandler<ExecutionException,?> EEH) {
return new Getter<T>(IEH, EEH);
}
#Override public From apply(Future<? extends From> from) {
if (from==null) throw new NullPointerException("Null argument in call with Getter.");
return getter(from, IEH, EEH);
}
private static <T> T getter(Future<T> src, ExceptionHandler<InterruptedException,?> IEH, ExceptionHandler<ExecutionException,?> EEH) {
try { return src.get(); }
catch (InterruptedException e) { IEH.handle(e); }
catch (ExecutionException e) { EEH.handle(e); }
return null;
}
}
which is used with the Guava libraries to do some embarrassingly-parallel calculations, and makes the actual Iterable transformation of Futures into something like Iterables.transform(futureCollection,Getter.make()) instead of tangle of inner-classes and exception handling.
I find the code honestly hard to follow and understand. It's full of static which is usually a bad sign in OO design and it's hard to follow with the generics.
Wouldn't something simpler like this work as well?
private static <T> T getter(Future<T> src) {
try { return src.get(); }
catch (InterruptedException e) { handle( "some text"); }
catch (ExecutionException e) { handle( e ) }
return null;
}
You can implement as many handle method as necessary in a base class (or in a static utility class) and use them in the catch block as necessary. Methods will be selected based on the signature, so if you want to print the text, you pass the string, if you want the stack trace you pass the exception (or both). Which leads to the combinations:
handle( String msg )
handle( Exception e )
handle( Exception e, String msg )
This solution has less if, which is usually a good sign as well.
But I have maybe missed a point, given that the code you published is just an excerpt of the whole code.
Have a look otherwise at this question, which is also related: Pluggable Error Handling Strategy
EDIT
If the solution I proposed above is too simple for your need, here are two other ways:
public class AbstractGetter<From> implements Function<Future<? extends From>, From> {
private abstract handleInterrupt( Exception e );
private abstract handleExecution( Exception e );
private static <T> T getter(Future<T> src ) {
try { return src.get(); }
catch (InterruptedException e) { handleInterrupt(e) }
catch (ExecutionException e) { handleExecution(e) }
return null;
}
}
And you implement the X concrete class that correspond the various exception handling strategies. That's essentially the template pattern.
You can still use delegation, but at a more coarse-grained level. Instead of providing individual handler, you provide a handler strategy. That's kind of variation of the strategy pattern then.
public interface ErrorStrategy
{
public void handleInterrupt(Exception e);
public void handleExecution(Exception e);
}
public class Getter<From> implements Function<Future<? extends From>, From> {
ErrorStrategy handler = new DefaultErrorStrategy(). // default one
public Getter<From>()
{
}
public Getter<From>( ErrorStrategy h )
{
this.handler = h.
}
private static <T> T getter(Future<T> src ) {
try { return src.get(); }
catch (InterruptedException e) { handler.handleInterrupt(e) }
catch (ExecutionException e) { handler.handleExecution(e) }
return null;
}
}
You can create the X error handling strategies that you need.
I think it's a good solution, but it could benefit from an ExceptionHandlerFactory and some xml files.