error: <identifier> expected - java

When I try to compile the Report.java I'm getting an error on line 6 saying: error: <identifier> expected aClient.setClientName("Michael"); with and arrow pointing to the first parenthese.
public class Client {
private String _clientName;
public String getClientName(){
return _clientName;
}
public void setClientName(String clientName){
_clientName = clientName;
}
}
public class Report {
Client aClient = new Client();
//ClientLawn aClientLawn = new ClientLawn();
aClient.setClientName("Michael");
//aClientLawn.setLawnWidth(10);
//aClientLawn.setLawnLength(10);
public void output(){
System.out.println(aClient.getClientName());
//System.out.println(aClientLawn.calcLawnSize());
}
}
I also want to make note that I am new to Java so please be gentle.

This line should be put into an initializer block:
{
aClient.setClientName("Michael");
}
So it it executed after creating the aClient.
The code here is run for every instance of the Report. Unfortunately you cannot set parameters to it. If you want to do so, put this block into the constructor:
public Report (String clientName) {
aClient.setClientName(clientName);
//aClientLawn.setLawnWidth(10);
//aClientLawn.setLawnLength(10);
}

Use instance initialization block.
public class Report {
Client aClient = new Client();
//ClientLawn aClientLawn = new ClientLawn();
{
aClient.setClientName("Michael");
//aClientLawn.setLawnWidth(10);
//aClientLawn.setLawnLength(10);
}
...
}

As everybody else pointed out, you cannot execute code outside of a method, so the following lines are illegal:
Client aClient = new Client();
aClient.setClientName("Michael");
They need to be wrapped within a method, such as the class' constructor:
public class Report {
public Report() {
Client aClient = new Client();
aClient.setClientName("Michael");
}
// ....
}
It looks like you want this code to be executable though, in which case you want to put all that in a main method such as:
public class Report {
public static void main(String... args) {
Client aClient = new Client();
aClient.setClientName("Michael");
System.out.println(aClient.getName());
}
}
You can then compile and execute the Report class.

Related

CLI with Picocli: Call main command before sub command get called

I switched from Apache Commons CLI to Picocli because of the sub command support (and annotation-based declaration).
Consider a command line tool like git, with sub commands like push. Git have a main switch --verbose or -v for enable verbose mode in all sub commands.
How can I implement a main switch that is executed before any sub commands?
This is my test
#CommandLine.Command(name = "push",
description = "Update remote refs along with associated objects")
class PushCommand implements Callable<Void> {
#Override
public Void call() throws Exception {
System.out.println("#PushCommand.call");
return null;
}
}
#CommandLine.Command(description = "Version control", subcommands = {PushCommand.class})
public class GitApp implements Callable<Void> {
#CommandLine.Option(names = {"-h", "--help"}, usageHelp = true, description = "Display this help message.")
private boolean usageHelpRequested;
#CommandLine.Option(names = {"-v", "--verbose"}, description = "Verbose mode. Helpful for troubleshooting.")
private boolean verboseMode;
public static void main(String[] args) {
GitApp app = new GitApp();
CommandLine.call(app, "--verbose", "push");
System.out.println("#GitApp.main after. verbose: " + (app.verboseMode));
}
#Override
public Void call() throws Exception {
System.out.println("#GitApp.call");
return null;
}
}
Output is
#PushCommand.call
#GitApp.main after. verbose: true
I would expect, that GitApp.call get called before the sub command get called. But only the sub command get called.
The CommandLine.call (and CommandLine.run) methods only invoke the last subcommand by design, so what you are seeing in the original post is the expected behaviour.
The call and run methods are actually a shortcut. The following two lines are equivalent:
CommandLine.run(callable, args); // internally uses RunLast, equivalent to:
new CommandLine(callable).parseWithHandler(new RunLast(), args);
Update: from picocli 4.0, the above methods are deprecated, and replaced with new CommandLine(myapp).execute(args). The "handler" is now called the "execution strategy" (example below).
There is also a RunAll handler that runs all commands that were matched. The following main method gives the desired behaviour:
public static void main(String[] args) {
args = new String[] { "--verbose", "push" };
GitApp app = new GitApp();
// before picocli 4.0:
new CommandLine(app).parseWithHandler(new RunAll(), args);
// from picocli 4.0:
//new CommandLine(app).setExecutionStrategy(new RunAll()).execute(args);
System.out.println("#GitApp.main after. verbose: " + (app.verboseMode));
}
Output:
#GitApp.call
#PushCommand.call
#GitApp.main after. verbose: true
You may also be interested in the #ParentCommand annotation. This tells picocli to inject an instance of the parent command into a subcommand. Your subcommand can then call methods on the parent command, for example to check whether verbose is true. For example:
Update: from picocli 4.0, use the setExecutionStrategy method to specify RunAll. The below example is updated to use the new picocli 4.0+ API.
import picocli.CommandLine;
import picocli.CommandLine.*;
#Command(name = "push",
description = "Update remote refs along with associated objects")
class PushCommand implements Runnable {
#ParentCommand // picocli injects the parent instance
private GitApp parentCommand;
public void run() {
System.out.printf("#PushCommand.call: parent.verbose=%s%n",
parentCommand.verboseMode); // use parent instance
}
}
#Command(description = "Version control",
mixinStandardHelpOptions = true, // auto-include --help and --version
subcommands = {PushCommand.class,
HelpCommand.class}) // built-in help subcommand
public class GitApp implements Runnable {
#Option(names = {"-v", "--verbose"},
description = "Verbose mode. Helpful for troubleshooting.")
boolean verboseMode;
public void run() {
System.out.println("#GitApp.call");
}
public static void main(String[] args) {
args = new String[] { "--verbose", "push" };
GitApp app = new GitApp();
int exitCode = new CommandLine(app)
.setExecutionStrategy(new RunAll())
.execute(args);
System.out.println("#GitApp.main after. verbose: " + (app.verboseMode));
System.exit(exitCode);
}
}
Other minor edits: made the annotations a bit more compact by importing the inner classes. You may also like the mixinStandardHelpOptions attribute and the built-in help subcommand that help reduce boilerplate code.
As Picocli supports inheritance with Options I've extracted the --help and --verbose Option into an abstract class BaseCommand and invoke super.call from the subcommands.
abstract class BaseCommand implements Callable<Void> {
#CommandLine.Option(names = {"-h", "--help"}, usageHelp = true, description = "Display this help message.")
private boolean usageHelpRequested;
#CommandLine.Option(names = {"-v", "--verbose"}, description = "Verbose mode. Helpful for troubleshooting.")
private boolean verboseMode;
#Override
public Void call() throws Exception {
if (verboseMode) {
setVerbose();
}
return null;
}
private void setVerbose() {
System.out.println("enter verbose mode");
}
}
#CommandLine.Command(name = "push",
description = "Update remote refs along with associated objects")
class PushCommand extends BaseCommand {
#Override
public Void call() throws Exception {
super.call();
System.out.println("Execute push command");
return null;
}
}
#CommandLine.Command(description = "Version control", subcommands = {PushCommand.class})
public class GitApp extends BaseCommand {
public static void main(String[] args) {
GitApp app = new GitApp();
CommandLine.call(app, "push", "--verbose");
}
#Override
public Void call() throws Exception {
super.call();
System.out.println("GitApp.call called");
return null;
}
}

How to dynamically handle commands in a chat program?

My question is more of a design issue than anything else. I'm currently developing a classic Server-Client chat program in Java. Everything is fine until I get to the commands. I thought it would be convenient for users to send commands that would then be treated by the server for changing their nickname for example. The thing is I want to make flexible code and above all, object-oriented code. To avoid endless if/else if statements to know what command was typed I believe it would be better to create a class for each command which inherit from a superclass Command. Then I could return the specific command through a getCommand() function overriden in all subclasses. But it does not solve my problem at all. The server still needs to test with instanceof what command has been returned. One way to do it dynamically would be to sort of auto downcasting it from the superclass Command and then call the appropriate function in the server class. For example:
public void processCommand(CommandNick c) {}
public void processCommand(CommandKick c) {}
But I haven't found any proper way of doing that and even if I did, I feel like there's still a design issue here. And I am convinced there is a nice and flexible way to do it but days weren't enough for me to figure it out. Any ideas? Thanks in advance! :)
I assume your server receives the message as an Object with a Sender and a String. Create your Command classes, and in the server init code, make a HashMap<String, AbstractCommand> with a String as key and your AbstractCommand class as value. Your commands should extend this class. Register all your commands, like so:
commandRegistry.put("help", new HelpCommandHandler());
I assume a command is a message with a ! before it. So when you receive a message, check if it is a command:
Message message = (Your Message)
String messageBody = message.getBody();
Sender messageSender = message.getSender();
if(messageBody.startsWith("!")) {
// Split the message after every space
String[] commandParts = messageBody.split(" ");
// The first element is the command base, like: !help
String baseCommand = commandParts[0];
// Remove the first character from the base, turns !help into help
baseCommand = baseCommand.substring(1, baseCommand.length());
// Creates a new array for the arguments. The length is smaller, because we won't copy the command base
String[] args = new String[commandParts.length - 1];
// Copy the elements of the commandParts array from index 1 into args from index 0
if(args.length > 0) {
System.arraycopy(commandParts, 1, args, 0, commandParts.length - 1);
}
// Your parse method
processCommand(sender, baseCommand, args);
}
public void processCommand(Sender sender, String base, String[] args) {
if(commandRegistry.containsKey(base)) {
commandRegistry.get(base).execute(sender, args);
} else {
// Handle unknown command
}
}
public abstract class AbstractCommand {
public abstract void execute(Sender sender, String[] args);
}
Sample implementation. I assume your server is a Singleton, and you can get on Object of it with Server.get() or any similar method.
public class HelpCommandHandler extends AbstractCommand { /* !help */
#Override
public void execute(Sender sender, String[] args) {
sender.sendMessage("You asked for help."); // Your code might not work like this.
}
}
public class ChangeNickCommandHandler extends AbstractCommand { /* !changenick newNick */
#Override
public void execute(Sender sender, String[] args) {
// I assume you have a List with connected players in your Server class
String username = sender.getUsername(); // Your code might not work like this
Server server = Server.get(); // Get Server instance
server.getUsers().get(username).setNickname(args[0]); // Argument 0. Check if it even exists.
}
}
// Server class. If it isn't singleton, you can make it one like this:
public class Server {
private static Server self;
public static Server init(/* Your args you'd use in a constructor */) { self = new Server(); return get(); }
public static Server get() { return self; }
private List<User> users = new List<User>();
private HashMap<String, AbstractCommand> commandRegitry = new HashMap<>();
// Make construcor private, use init() instead.
private Server() {
commandRegistry.put("help", new HelpCommandHandler());
commandRegistry.put("changenick", new ChangeNickCommandHandler());
}
// Getters
public List<User> getUsers() {
return users;
}
public HashMap<String, AbstractCommand> getRegistry() {
return commandRegistry;
}
}
This is a bit of pseudo code to illustrate that your controller doesn't need to know about the command processors (no need for instanceof).
abstract class CommandProcessor {
/* return boolean if this Command processed the request */
public static boolean processCommand(String command, User user, Properties chatProperties, Chat chat);
}
/* Handle anything */
public class CommandRemainder extends CommandProcessor {
#Override
public static boolean processCommand(String command, User user, Properties chatProperties, Chat chat) {
chat.appendText("[" + user.getName() + "] " + command);
return true;
}
}
/* Handle color changing */
public class CommandColorizer extends CommandProcessor {
protected static List<String> ALLOWED_COLORS = new ArrayList<>(Arrays.asList("red", "blue", "green"));
#Override
public static boolean processCommand(String command, User user, Properties chatProperties, Chat chat) {
if ("fg:".equals(command.trim().substring(0,3)) {
String color = command.trim().substring(3).trim();
if (ALLOWED_COLORS.contains(color)) {
chat.setForeground(color);
}
return true;
}
return false;
}
}
public class ChatController {
protected Chat chat = new Chat();
protected User user = getUser();
protected Properties chatProperties = getChatProperties();
protected List<CommandProcessor> commandProcessors = getCommandProcessors();
{
chat.addChatListener(new ChatListener(){
#Override
public void userChatted(String userChatString) {
for (CommandProcessor processor : commandProcessors) {
if (processor.processCommand(userChatString, user, chatProperties, chat)) {
break;
}
}
}
});
}
List<CommandProcessor> getCommandProcessors() {
List<CommandProcessor> commandProcessors = new ArrayList<>();
commandProcessors.add(new CommandColorizer());
commandProcessors.add(new CommandRemainder()); // needs to be last
return commandProcessors;
}
}

Call a static method from abstract class

I have a class like this
parent class DevPortalTestController is absract
public class SeleniumWebDriverFactory extends DevPortalTestController {
public static RemoteWebDriver mDriver;
public SeleniumWebDriverFactory(RemoteWebDriver whichDriver)throws UnsupportedOSException, PoisonException {
super(whichDriver);
mDriver = whichDriver;
}
public List<TestContext> getBrowserTestContext(List<String> browsers)
throws Exception {
PhoenixDriver driver = null;
List<TestContext> contexts = new ArrayList<TestContext>();
logger.info("Setting browser context...");
Login login = retrieveLoginData();
for (String browser : browsers) {
// operations
Map<String, Object> browserMap = new HashMap<String, Object>();
// Populate the map with DevPortalTestController objects.
browserMap.put(MasterConstants.BROWSER, this);
.....
.....
}
return contexts;
}
public static List<TestContext> getTestContext(List<String> browsers)
throws Exception {
SeleniumWebDriverFactory instanceSel = new SeleniumWebDriverFactory(mDriver);
List<TestContext> contexts = instanceSel.getBrowserTestContext(browsers);
return contexts;
}
}
I need to call this getTestContext method in another class
for that am doing like this.Also that class is extenting another parnet class
public class DevPortalTest extends Test {
RemoteWebDriver rmDriver ;
SeleniumWebDriverFactory selFac =new SeleniumWebDriverFactory(rmDriver);
#Override
public List<TestContext> getTestContexts() {
try {
String os = System.getProperty("os.name");
if (SystemDetail.deviceIsRunningWindows()) {
return selFac.getTestContext(ZucchiniConstants.allBrowsers);
else {
throw new TestException(os + " is not supported");
}
} catch (Exception e) {
logger.error("", e);
}
return null;
}
}
But in this place
SeleniumWebDriverFactory selFac =new SeleniumWebDriverFactory(rmDriver);
I'm getting
Default constructor cannot handle exception type PoisonException
thrown by implicit super constructor. Must define an explicit
constructor
How can i call the method getTestContext inside DevPortalTest test class?
The problem is that initializer code will be placed in the "default constructor" which cannot throw any exception. Define an empty constructor that throws the exceptions to proceed.
e.g.,
DevPortalTest() throws UnsupportedOSException, PoisonException { }
You have to add the constructor to your test code:
public DevPortalTest() throws UnsupportedOSException, PoisonException {
SeleniumWebDriverFactory selFac = new SeleniumWebDriverFactory(rmDriver);
}
also, i assume you're injecting RemoteWebDriver rmDriver;
Since the method is static, you don't need an object to call it.
SeleniumWebDriverFactory.getTestContext(ZucchiniConstants.allBrowsers);
As an alternative to creating a constructor you can also do this
public class DevPortalTest extends Test {
RemoteWebDriver rmDriver ;
SeleniumWebDriverFactory selFac;
// this code block runs before constructor
{
try{
selFac = new SeleniumWebDriverFactory(rmDriver);
}catch(Exception e){
// handle exception
}
}
Static method can be accessed using class Name so there is no need to create any Object in Abstract class.

Type symbol not found in inner class

[EDIT: I've rewritten the code to further simplify it and focus on the issue at hand]
I'm working on this particular piece of code:
class SimpleFactory {
public SimpleFactory build() {return null}
}
class SimpleFactoryBuilder {
public Object build(final Class builderClazz) {
return new SimpleFactory() {
#Override
public SimpleFactory build() {
return new builderClazz.newInstance();
}
};
}
}
However, the builder in the return statement triggers the error "Cannot find symbol newInstance". It's as if builderClazz wasn't recognized as a class object.
How can I make it work?
EDIT: SOLUTION (thanks to dcharms!)
The code above is a partial simplification of the code I was dealing with. The code below is still simplified but includes all the components involved and includes the solution provided by dcharms.
package com.example.tests;
interface IProduct {};
interface ISimpleFactory {
public IProduct makeProduct();
}
class ProductImpl implements IProduct {
}
class SimpleFactoryBuilder {
public ISimpleFactory buildFactory(final Class productMakerClazz) {
return new ISimpleFactory() {
#Override
public IProduct makeProduct() {
try {
// the following line works: thanks dcharms!
return (IProduct) productMakerClazz.getConstructors()[0].newInstance();
// the following line -does not- work.
// return new productMakerClazz.newInstance();
}
catch (Exception e) {
// simplified error handling: getConstructors() and newInstance() can throw 5 types of exceptions!
return null;
}
}
};
}
}
public class Main {
public static void main(String[] args) {
SimpleFactoryBuilder sfb = new SimpleFactoryBuilder();
ISimpleFactory sf = sfb.buildFactory(ProductImpl.class);
IProduct product = sf.makeProduct();
}
}
You cannot instantiate a new object this way. builder is a Class object. Try instead the following:
return builder.getConstructors()[0].newInstance(anInput);
Note: this assumes you are using the first constructor. You may be able to use getConstructor() but I'm not sure how it would behave with the generic type.

Java Compilation error "method setSchema in class MpsPojo cannot be applied to given types;"

Hi I saw some of the related question related to this but didn't find any to the point solution.
I have a POJO class defined as:
MpsPojo.java
public class MpsPojo {
private String mfr;
private String prod;
private String sche;
public String getMfr() {
return mfr;
}
public void setMfr(String mfr) {
this.mfr = mfr;
}
public String getProd() {
return prod;
}
public void setProd() {
this.prod = prod;
}
public String getSchema() {
return sche;
}
public void setSchema() {
this.sche = sche;
}
}
I have 2nd business Logic as:: MpsLogic.java
public class MpsLogic {
public void calculateAssert(MpsPojo mpspojo){
String manufacturer;
String product;
String schema;
manufacturer = mpspojo.getMfr();
product = mpspojo.getProd();
schema = mpspojo.getSchema();
String url = "http://localhost:9120/dashboards/all/list/"+manufacturer+"/"+product+"/"+schema;
}
}
And final class, the Test class is :: FinalLogic.java
public class FinalLogic {
MpsPojo mpspojon = new MpsPojo();
MpsLogic mpslogicn = new MpsLogic();
#Test
public void firstTest() {
mpspojon.setMfr("m1");
mpspojon.setProd("p1");
mpspojon.setSchema("sch1");
mpslogicn.calculateAssert(mpspojon);
System.out.println("Printing from Final class");
}
}
In program FinalLogic.java, this gives me the Compilation error error method setSchema in class MpsPojo cannot be applied to given types;
But when I comment the lines mpspojon.setProd("p1"); and mpspojon.setSchema("sch1"); then this works fine without error.
I debugged a lot but dint find any clue for this. Any help will be very helpful for me.
Thanks
Add String arguments to setProd and setSchema as you have already done with setMfr:
public void setProd(String prod) {
^ ^
and
public void setSchema(String sche) {
^ ^
setSchema() receives no parameters in your declaration. Change it to:
public void setSchema(String sche) {
this.sche = sche;
}
Same holds true for setProd
If you use any IDE, I advise you:
look into the warnings that you will get (the assignment this.sche = sche will give warning The assignment to variable thing has no effect in case of no argument method).
Generate the setters/getters automatically, don't code them by yourself (thus avoiding any possible typing mistakes). E.g. in Eclipse that will be alt+shift+s, then r

Categories

Resources