I have a question about combining java with javascript. In our application we have gui build in javascript and server side build in java. In javascript we write that we want to call methodX from classY in java. The problem is that java doesen't know anything about javascript so when we change something in java we could break javascript code. Even plain refactor option in eclipse can break our javascript without knowing (changing method name, removing params, renaming setter and getter in DTO object). The question is how to counteract against it. I was thinking about writing some annotations in java so after changing method signature you will get compilation error (is it even possible to write this kind of annotation) but I don't want to reinvent the wheel again if there is some kind of tool which will do it for me. I would be grateful for any help.
The question is how to counteract against it.
Probably the most practical solution is to develop a set of automated tests (e.g. unit or system tests) that are specifically designed to "exercise" all of the cases where there is a Java API that is called from Javascript (or vice-versa)
I think there are a couple of solutions(workarounds) for your problem.
1)Mapping certain strings with methods.
public class JavascriptCallable {
private static final String jsIdentifierMethod1 = "method1";
private static final String jsIdentifierMethod2 = "method2";
/**
* All requests from JS should be redirected to this method.
*
* #param methodName Name of the method
*/
public void requestFromJavascript (String methodName) throws Exception {
if (methodName.equals(jsIdentifierMethod1)){
method1();
} else if (methodName.equals(jsIdentifierMethod2)){
method2();
} else{
throw new Exception("Method not supported");
}
}
public void method1(){
// Do something
}
public void method2() {
// Do something
}
}
2)Having separate methods eligible for js calling. This will help if you are using reflections to call the methods
public class JavascriptCallable {
/*----------------Methods to be called by js. Never refractor------------------*/
public void noRefractorMethod1() {
method1();
}
public void noRefractorMethod2() {
method2();
}
/*-------------------------------------------------------------------------------*/
/*---------Methods with business logic. Refractoring these will not mess your js-----------*/
public void method1() {
// Business logic
}
public void method2() {
// Business logic
}
/*-------------------------------------------------------------------------------*/
}
Please let me know if this helps.
Related
Today I was thinking about a nice way to write less code for a common functionality that is required for different objects.
Inheritance can do the job but then the classes won't be able to inherit from anyone else, so I chose Interfaces.
So I have my interface with the functionality I will need for some objects:
public interface Test {
String message = "Hello from Interface!";
default void printMessage() {
System.out.println(message);
}
}
And then I can use it in any object without having to override/write any code more than just simply calling the method when needed:
public class TestingTest implements Test {
public String message = "Hello from Class!";
public TestingTest() {
printMessage();
}
public static void main(String[] args) {
new TestingTest();
}
}
It works like a charm! But... Then I thought, what if I want some of those objects to specify a different message without being required (optional), well first thing I thought was to shadow the interface variable, but it doesn't work, the default method keeps using the variable from the interface instead of the class variable (which shadowed it).
A solution of course would be to overload the printMessage method in the interface so it recieves the message as a parameter for when the user requires to specify the message, but is there any more elegant way? Something like simply just declaring a new message in the class?
The String message in the interface is static (AFAIK). So that scheme does not work.
You might do something (ugly) as:
default void printMessage(String... messages) {
if (messages.length == 0) {
messages = new String[] { "arrgg" };
}
System.out.println(messages[0]);
}
Fields have no inheritance, so the value can only stem from an overridable method like
public String message() { return "..."; }
What you want is a functionality in n classes that should also be modifiable, if needed.
To be honest, your example is a little bit abstract and thus my answer will be abstract, too.
public interface Test {
void printMessage();
default void printMessage(String message) {
System.out.println(message);
}
}
public class TestingTest {
private final test;
public TestingTest(Test test) {
this.test = test;
}
public void someMethod() {
test.printMessage("Hello from class");
}
}
Additionally, you would have a class that implements the interface and offers the message. This way you could group your objects, change the message, make more complex logging and you would actually see the dependency from outside.
In my opinion, you are misusing the interface. An interface offers public methods to call it from outside, but you want to use them inside like they were private functionalities for the class.
Just use objects instead.
I have developed below code with the intention to remove if else conditions so that code cyclomatic complexity should be less.
For this I have used reflection api and wrote method which takes condition as an argument and called respective method on the condition name basis.
This works fine, I want to know is it a good idea to use reflection (This code) in web application, so that I am free from checking conditions.
For example in below code we have different method with prefix state ex: stateSUBMIT, stateWithdraw etc.
we can call stateSUBMIT method by passing only "SUBMIT".
public class Participate {
public String execute(String methodName) {
String st = null;
try {
Method method = this.getClass().getDeclaredMethod(
"state" + methodName);
method.invoke(this);
} catch (Exception e) {
e.printStackTrace();
}
return st;
}
public void stateSUBMIT() {
System.out.println("in SUBMIT");
}
public void stateWithdraw() {
System.out.println("in Withdraw");
}
public void state() {
System.out.println("in state ");
}
public void statenull() {
System.out.println("in null ");
}
public static void main(String[] args) {
Participate p = new Participate();
p.execute("SUBMIT");
}
}
This is valid code, but can be achieved without reflections.
Step One: Define an interface
public interface Command {
public void execute();
}
Step Two: Create Concrete Implementations
public class StateCommand implements Command {
public void execute() {
// Your code.
}
}
Step Three: Add a collection of these to your original class
private Map<String, Command> commands;
Step Four: Populate
public MyClass() {
commands = new HashMap<String, Command>();
commands.put("state", new StateCommand());
}
Get that class and execute
public String callMethod(String name) {
Command command = commands.get(name);
if(command != null) {
command.execute();
}
}
This is just a relatively simple alternative to using reflections, which should be considered as a last resort.
I would avoid it. There are better alternatives. You could pick one of all the numerous web frameworks or you could code something similar without reflection. For example, use a HashMap from the action (SUBMIT, ...) to an object that implements an interface. That way you can call a method with parameters without reflection, which is slow and which provides no compile-time validations. This is not a recommendation (go with a framework!), but it is a better way of doing what you are doing right now.
Your implementation is beneficial in case if you are doing for making this Generic approach for all other other classes in your project.Its good if you are having re usability of this in many other scenarios.
But if its only for specific implementation which is not generalized then there are many simple ways to do this job, because if you will use java reflections than there is some amount of time complexity involved which is comparatively less if you do it without using reflectns.
What is the real reason that in Java, and similar languages, must be explicitly said that a class implements an interface?
Imagine implicit implementation:
interface Flyer { void fly(); }
public class Duck { public void fly() {...} }
public class Plane { public void fly() {...} }
public class Hoe { void hangAround() {...} }
void startFlying(Flyer flyer) {...}
void race() {
...
startFlying(duck); // OK
startFlying(plane); // OK
startFlying(hoe); // Compilation error.
}
Compiler knows method's signatures, return type (and modifier, of course). At this point it seems clear that there is no need to explicitly specify that Duck and Plane implements Flyer.
I would said that "implements XYZ" may be removed from Java without worries.
No difference, check at compilation time so it's OK.
In the other hand:
#JBNizet mentioned different meaning of methods with the same signature and return type.
I will use his example:
interface Runner { void run(); }
public class Guy { public void run(); }
public class Gal { public void run(); }
void startRunning(Runner r) {...}
void race() {
startRunning(guy); // OK
startRunning(gal); // OK
startRunning(runnableThread); // OK
}
OK for compiler, OK for startRunning() (OK for me). It's up to your philosophy if this is OK for you or not.
Explicit:
public class Guy **implements Runner **{ public void run(); }
public class Gal **implements Runner **{ public void run(); }
In bold (or text between ** and **) is the price which you must pay for
void race() {
startRunning(guy); // OK
startRunning(gal); // OK
startRunning(runnableThread); // Compilation error!
}
Note compilation error so you can see the issue before testing.
If it's intended to use runnableThread in startRunning() as well you must do it even more explicitly (enough time to realize what you are doing).
"I wondered how much of time is wasted by resolving issues related to typing "implements XYZ" compared to time wasted by resolving issues with implicitly implemented interfaces. If it's way more better for implicitly implemented interface then I hate Java designers for their decision and that they force us to belive it's better :-)"
Ladybug and airbus (and duck)
I think the issue with implicitly implemented interface is only theoretical and rare in real.
public class Airbus {
void takeOff() {...}
void land() {...}
Passenger[] getPassengers() {...}
}
public class Ladybug {
void takeOff() {...}
void land() {...}
}
public class Duck {
void takeOff() {...}
void land() {...}
Passenger[] getPassengers() {...}
}
public interface Aircraft {
void takeOff();
void land();
Passenger[] getPassengers();
}
public void fly(Aircraft aircraft) {
aircraft.takeOff();
for (Passenger p : aircraft.getPassengers()) {...}
aircraft.land();
}
public void airport() {
fly(airbus_a380); // OK
fly(ladybug); // Compilation error, does not match Aircraft requirements.
fly(duck); // OK
}
public interface Lander {
void land();
}
public void landAtMeadow(Lander lander) {...}
public void meadow() {
landAtMeadow(airbus_a380); // OK
landAtMeadow(duck); // OK
landAtMeadow(ladybug); // OK
}
All of them are matching requirements of landAtMeadow so they can be used in that context. Even it may not be possible to land at meadow for airbus_a380 (In other word testing is required) you need to land there in emergency.
Do not forget that landAtMeadow() may have more specific requirements like
public interface Lander { void landAtLimitedArea(int size); }
to say that the space is limited, so if airbus_a380 does not support this method then you have compilation error here.
Java is a strong typed language, so the assignation of an instance to an interface typed variable must be validated at compile time. This can only be done by explicitly declared interface implementations.
As others have said, this is a basic characteristic of the Java language. It's there for good reasons, folks who are doing serious largescale programming like it, and there's absolutely no reason to change it.
If it bothers you, I strongly recommend that you find another language that is more weakly typed and use that instead. There are a fair number of languages these days which can be compiled into Java bytecodes and used in a Java environment, so you might not even have to give up the flexibility of being able to run in a JVM.
My friend In a strongly typed languages, for ex: in C or Java, when a variable or reference is declared, it must be informed to the compiler what data type the variable or reference is of
When a class is declared to implement an interface X then any other method working with interface X is sure that all the necessary methods are implemented in the class (and therefore they do not need to check every time if needed method is implemented). If there was no such declaration, then any method using classes which implement X would need to:
ensure that the class of object whith which the method is working implements all methods necessary (so go through all the methods of the class searching the ones you want every time you expect to work with interface X - instead of doing this once, at compilation).
have many error handling lines of code implemented (what to do, if I expect method A to do something, but method A it is not there at all?)
Static typing adds much to code's safety in general, as many errors are possible to detect at compilation. Why try to change Java from staticaly to dynamicaly typed? There are many dynamicaly typed languages out there, with their pluses and minuses, ready to use (Python, for example).
I am following an older Java tutorial that is teaching the concept of the Service layer, my program is a very simple program that will create a list of Bills and their due dates. Where I am stuck is in creating the JUnit Test for factory methods.
First here is the Bill Constructor
public Bill(String bname, Double bamount, Date bdate, String bfrequency){
this.billName = bname;
this.billAmount = bamount;
this.billDueDate = bdate;
this.frequency = bfrequency;
}
Next is the Interface to save and get these bills
public interface IBill {
public void save(Bill bill);
public Bill read(Bill readbill);
}
Bear with me, next is the concrete implementation of the interface which are stubbed out for now, nothing implemented yet
public class BillSvcImpl implements IBill {
#Override
public void save(Bill bill) {
System.out.println("Entering the Store BillInfo method");
}
#Override
public Bill read(Bill readbill) {
System.out.println("Entering the Read BillInfo method");
return null;
}
}
Then there is the factory method that will create/call the concrete implementation
public class Factory {
public IBill getBillInfo(){
return new BillSvcImpl();
}
}
Then finally the JUnit test where I am stucked
public class BillSvcTest extends TestCase {
private Factory factory;
#Before
public void setUp() throws Exception {
super.setUp();
factory = new Factory();
}
#test
public void testSaveBill(){
IBill bill = factory.getBillInfo();
Bill nanny = new Bill("Nanny",128d,new Date(6/28/2013),"Montly");
bill.save(nanny);
//what goes here??, Assert??
}
#test
public void testReadBill(){
//How can I write a Test for this??
//Please help
}
}
The instruction is
Create a JUnit Test for your service, The test should use the Factory to get the service, instantiated in the setUp() method.
My service/interface have two methods save and get, how can I create a test for these before I start the actual implementation.
Any help is appreciated.
Thanks
First, don't extend TestCase - instead, use JUnit 4.x.
Second, I take great umbrage against a method with side effects. There's no reason to modify your save method to return a boolean instead of void; you just have to take an alternative approach to testing the method.
Third, I'm of the persuasion that a simple unit test won't be able to cover the save functionality of this method. Something that reads like it would be persisted someplace is better suited for an integration test of some kind (using the database, ensuring that the file exists and the contents are correct, etc).
The main question you want to answer when you're unit testing is, "What is the expected result of this method invocation given this parameter?" When we call save, what do we expect to happen? Do we write to a database? Do we serialize the contents and write to a file? Do we write XML/JSON/plain text out? That would have to be answered first, and then could a useful test be written around it.
The same thing applies for read - what do I expect to receive as input when I attempt to read a bill? What do I gain from passing in a Bill object, and returning a Bill object? (Why would an outside caller have a notion of a bill that I'm trying to read?)
You have to flesh out your expectations for these methods. Here's an approach I use to write unit tests:
Given a specific input,
when I call this method,
then I expect these things to be true.
You have to define your expectations before you can write the unit tests.
IMO save method should return something to say whether Bill got saved or not. I would have kept save method like this
public boolean save(Bill bill) {
System.out.println("Entering the Store BillInfo method");
boolean result = false;
try {
//..... saving logic
result = true;
}
catch(Exception e) {
result = false;
e.printStackTrace();
}
return result;
}
and did an assert in the testcase as
#Test
public void testSaveBill(){
//Success
IBill bill = factory.getBillInfo();
Bill nanny = new Bill("Nanny",128d,new Date(6/28/2013),"Montly");
assertTrue(bill.save(nanny));
//Failure
assertFalse(bill.save(null));
}
Generally, implementation of read() and store() involves integrating with external system such as database, file system. This makes the test go hand in hand with the external system.
#Test
public void insertsBillToDatabase() {
//setup your database
bill.store(aBill);
//fetch the inserted bill then assert
}
These tests are focused on whether you component is making an correct abstration on the external system.
Tests depending on external system are expensive because they are relatively slow and difficult to setup/cleanup. You'd better seperate business conerns and integration concerns if there are some complex business logic in the store().
public void store(Bill bill) {
//business logic
billDao.save(bill); // delegate to an injected dao, you can replace it with a test double in test code
}
#Test
public void doesSthToBillBeforeSave() {
//replace your billDao with a stub or mock
bill.store(aBill);
//assert the billDao stub / mock are correctly invoked
//assert bill's state
}
I have a method that I've created that I would like to be able to use anywhere, but I don't know what the best practice is for giving access to that method throughout the project. Do I just create a .java file with a public method and that will give access throughout? Will I need to declare it anywhere (somewhere in the manifest?)?
I'm sure this has been asked, but I am not returning anything useful on my google searches. I am not good enough at googling for Android, yet! Sorry for adding to the duplicates, if I am.
You have a few options. The simplest is a public static method.
public class MyClass {
public static MyReturnType myMethod(MyArgumentType input) {
// my code here
}
}
You will now be able to call this like:
MyClass.myMethod(arg);
Use static methods. As for me, if I want to store just methods in the same place I create a new class and all of the methods are static. For example.
public static int parseInt(String str)
{
try
{
return Integer.parseInt(str);
}
catch (NumberFormatException e)
{
return -1;
}
}
If it's just do anything and doesn't require to save state in the class, this is the best solution.
Here's a sample of a static method.
public class Messages {
public static String mySpecialFinalMessage(){
return "Hello Stackoverflow";
}
}
You no longer need to create an Instance of Messages to call mySpecialFinalMessage() because it is a static. The best practice to call a static method is in this format CLASSNAME.STATICMETHODNAME();
So in our example,
Messages.mySpecialFinalMessage()
Please Note that you calling static methods inside non-static method is legal however, calling non-static methods inside static methods will give you a compile time error.
this is legal
public class MyMessage {
public String getMessage(){
return Messages.mySpecialFinalMessage();
}
}
Take note taht Messages.mySpecialFinalMessage() is that static method. Also, Notice that we did not create an instance of Messages to call mySpecialFinalMessage(), rather we've just called it directly by CLASSNAME.STATICMETHODNAME