I'm looking for a way to pass a parameter to a custom Gradle task. (Gradle 5.1.1)
I have created a task:
public class MyTask extends DefaultTask {
private String url;
#Optional
public void setUrl(String url) {
this.url = url;
}
#Input
public String getUrl() {
return url;
}
#TaskAction
public void run() {
System.out.println("URL IS " + getUrl());
}
}
This is similar to the example given at:
https://docs.gradle.org/current/userguide/custom_tasks.html#example_declaring_a_command_line_option
On the next step i created a plugin which hosts this task.
public class MyPlugin implements Plugin<Project>, TasksProducingPlugin {
#Override
public void apply(Project project) {
MyTask myTask = project.getTasks().create("exampleTask", MyTask.class);
myTask.setDescription("...");
myTask.setGroup(TASK_GROUP_NAME);
myTask.run();
#Override
public Collection<String> taskNames() {
Collection<String> collection = new HashSet<>();
collection.add("exampleTask");
return collection;
}
}
Now i want to run the exampleTask from the command line and provide the value for the url.
I try:
gradlew exampleTask --url=http://www.google.com/
And get:
Unknown command-line option '--url'.
Also tried:
gradlew exampleTask -Purl=http://www.google.com/
And get:
No value has been specified for property 'url'.
What am i doing wrong?
Look at the documentation again. You have annotated your setter method with #Optional instead of #Option.
Related
is it posible to generate a custom "presence checking" method name, being a method of the property itself rather the owning object?
I know I can use hasProperty() methods to check for presence of a value...
https://mapstruct.org/documentation/stable/reference/html/#source-presence-check
but with Optional or JsonNullable (from OpenApi nonullable) that checking method is on the property itself, not on the owning object... :-(
I can map JsonNullable or Optional easyly 'using' or extending a simple custom Mapper
#Mapper
public class JsonNullableMapper {
public <T> T fromJsonNullable(final JsonNullable<T> jsonNullable) {
return jsonNullable.orElse(null);
}
public <T> JsonNullable<T> asJsonNullable(final T nullable) {
return nullable != null ? JsonNullable.of(nullable) : JsonNullable.undefined();
}
}
what I would like to achieve is something like this as "presence check":
if(source.getProperty().isPresent()) {
target.set(customMapper.map(source.getProperty()));
}
Any one found a solution for this?
Thanks and regards
I have managed to implement custom lombok extension which generates "presence checknig" methods.
Here is an example project. In short I added #PresenceChecker annotation and implemented Lombok Javac Annotation handler.
It's possible to use it together with other Lombok annotations:
#Getter
#Setter
public class User {
private String name;
}
#Getter
#Setter
#PresenceChecker
public class UserUpdateDto {
private String name;
}
//MapStruct Mapper interface declaration
#Mapper
public interface UserMapper {
void updateUser(UserUpdateDto dto, #MappingTarget User user);
}
Generated code:
public class User {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
public class UserUpdateDto {
private boolean hasName;
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
this.hasName = true;
}
public boolean hasName() {
return this.hasName;
}
}
//MapStruct Mapper implementation
public class UserMapperImpl implements UserMapper {
#Override
public void updateUser(UserUpdateDto dto, User user) {
if ( dto == null ) {
return;
}
if ( dto.hasName() ) {
user.setName( dto.getName() );
}
}
}
The answer is unfortunately a straight no.
It is not possible in the current version of MapStruct (1.3.1final) and its not on the shortlist for 1.4.0. You could open up an issue on the git repo of MapStruct as feature request.
How to get the property of sonar-project.properties from the Sonar java custom rules.
I have written a class , but it return null. I am using SONARQUBE 7.0
public class PropertyFinder {
private static final Logger LOG = LoggerFactory.getLogger(PropertyFinder.class);
public static Configuration settings = null;
public PropertyFinder(Configuration settings) {
this.settings = settings;
}
public static Settings getSettings() {
return settings;
}
Also
public class JavaRulesPlugin implements Plugin {
public static final String FILE_SUFFIXES_KEY = "sonar.java.file.suffixes";
#Override
public void define(Context context) {
context.addExtension(JavaRulesDefinition.class);
context.addExtension(PropertyFinder.class);
context.addExtension(SonarJavaFileScannersFactory.class);
}
I call PropertyFinder.getSettings() from Custom rule but it returns null.
public abstract class CustomBaseTreeVisitor extends BaseTreeVisitor implements JavaFileScanner {
private Configuration settings = PropertyFinder.getSettings();
}
I try to config cqrs and event sourcing with axon.
SeatReseveCreateCommand is work properly. but SeatReserveUpadateCommand is not work correct.
this is my SeatReserve aggregate
#Aggregate
public class SeatReserve {
#AggregateIdentifier
private String id;
private String seatid;
private Date date;
#SuppressWarnings("unused")
private SeatReserve() {
}
#CommandHandler
public SeatReserve(SeatReseveCreateCommand seatReseveCreateCommand) {
apply(new SeatReseveCreateEvent(seatReseveCreateCommand.getMyid(), seatReseveCreateCommand.getSeatId(),
seatReseveCreateCommand.getDate()));
}
#CommandHandler
public SeatReserve(SeatReserveUpadateCommand upadateCommand) {
apply(new SeatReserveUpadateEvent(id, upadateCommand.getSeatId()));
}
#EventSourcingHandler
public void on(SeatReseveCreateEvent seatReseveCreateEvent) {
this.id = seatReseveCreateEvent.getId();
this.seatid = seatReseveCreateEvent.getSeatId();
this.date = seatReseveCreateEvent.getDate();
}
#EventSourcingHandler
public void on(SeatReserveChangeEvent upadateEvent) {
seatid = upadateEvent.getSeatId();
}
}
this is my controller
#RestController
public class TestController {
private final CommandGateway commandGateway;
public TestController(CommandGateway commandGateway) {
this.commandGateway=commandGateway;
}
#PostMapping
public String fileComplaint(#RequestBody Map<String, String> request) {
String id = UUID.randomUUID().toString();
SeatReseveCreateCommand command=new SeatReseveCreateCommand(id,request.get("seatid"),new Date(request.get("date")));
commandGateway.send(command);
return id;
}
#PatchMapping
public String fileComplaintUpdate(#RequestBody Map<String, String> request) {
SeatReserveUpadateCommand command= new SeatReserveUpadateCommand(request.get("id"),request.get("seatid"));
commandGateway.send(command);
return request.get("id");
}
}
I try to send request using postman
this is my create request
this is my update request
update make this error
2018-01-03 10:44:53.608 WARN 11138 --- [nio-8085-exec-1] o.a.c.gateway.DefaultCommandGateway : Command 'com.thamira.research.api.bankaccount.SeatReserveUpadateCommand' resulted in org.axonframework.eventsourcing.IncompatibleAggregateException(Aggregate identifier must be non-null after applying an event. Make sure the aggregate identifier is initialized at the latest when handling the creation event.)
how can I solve this.
The problem is that your update command is defined as a constructor. The command should go to the already existing aggregate instance.
Changing the command handler to:
#CommandHandler
public void handle(SeatReserveUpadateCommand upadateCommand) {...}
should fix the issue.
I am writing a custom plugin for Gradle. I want to be able to have:
serviceDependencies {
service name: 'service1', version: '1.0'
service name: 'service2', version: '1.1'
}
In my Plugin implementation (in Java) I have:
public void apply(final Project project) {
project.getExtensions().create("serviceDependencies", Services.class);
project.getExtensions().create("service", Service.class);
}
And Service.java:
public class Service {
private String name;
private String version;
public Service(final String name, final String version) {
this.name = name;
this.version = version;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
public String getVersion() {
return this.version;
}
public void setVersion(final String version) {
this.version = version;
}
}
When I try use this plugin I get:
java.lang.IllegalArgumentException: Could not find any public constructor for class com.xxx.xxx.Service_Decorated which accepts parameters [].
This still happens when I remove serviceDependencies/Services.java from the picture.
If I remove the Service constructor or remove the arguments.
org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method service() for arguments [{name=service1, version=1.0}] on root project ...
Obviously my pojo is being decorated, but not quite with the correct constructor. How can I get the constructor to work how I want in my build.gradle script?
A second and independent question is what should Services.java look like?
I would only register one extension for serviceDependencies {} that exposes functions to register your services:
public class Services {
void service(String name, String version) { /* new Service(...) */ }
}
project.getExtensions().create("serviceDependencies", Services.class);
This would allow Java, Kotlin and Groovy consumer to do something like:
serviceDependencies {
service 'service1', '1.0'
service 'service2', '0.1'
}
Then if you want to support Groovy named arguments you'd need to add:
public class Services {
void service(String name, String version) { /* new Service(...) */ }
void service(Map<String, String> namedArguments) {
service(namedArguments.get("name"), namedArguments.get("version"))
}
}
This would allow Groovy consumers to do:
serviceDependencies {
service name: 'service1', version: '1.0'
service name: 'service2', version: '0.1'
}
Here is my ConfigUpdater class
private final class ConfigUpdater implements ManagedService {
#SuppressWarnings("rawtypes")
#Override
public void updated(Dictionary config) throws ConfigurationException {
if (config == null) {
return;
}
String title = ((String)config.get("title"));
}
}
My question is how can I access String title in any other class? Or how can I get config dictionary in any other class... Method updated will only be called when a config file is changed... once it is changed how can access its data in other class?
In general you would create a service that exposes these properties to other components.
For example, you could give your ConfigUpdater a second interface. Another component can than lookup/inject this interface from the service registry and use it's methods to access the properties.
I created an example project on GitHub: https://github.com/paulbakker/configuration-example
The most important part is the service that implements both ManagedService and a custom interface:
#Component(properties=#Property(name=Constants.SERVICE_PID, value="example.configurationservice"))
public class ConfigurationUpdater implements ManagedService, MyConfiguration{
private volatile String message;
#Override
public void updated(#SuppressWarnings("rawtypes") Dictionary properties) throws ConfigurationException {
message = (String)properties.get("message");
}
#Override
public String getMessage() {
return message;
}
}
The configuration can then be used like this:
#Component(provides=ExampleConsumer.class,
properties= {
#Property(name = CommandProcessor.COMMAND_SCOPE, value = "example"),
#Property(name = CommandProcessor.COMMAND_FUNCTION, values = {"showMessage"}) })
public class ExampleConsumer {
#ServiceDependency
private volatile MyConfiguration config;
public void showMessage() {
String message = config.getMessage();
System.out.println(message);
}
}