why main() is not necessary in action classes of struts2 ? - java

*Hello Guys..! *
Normally a java program needs main() function to execute the code otherwise it'll returns an error[java.lang.NoSuchMethodError: main Exception in thread "main"]..! In struts2 we are using action classes & bean classes(java codes) but they don't needs main() function in it. What is the concept behind this..? By the way I'm a newbie to the Struts framework.

This is because the Struts framework provides the infrastructure to get the application up and running. As a user of the framework, you implement specific classes that are called by the framework code.
Struts itself runs inside an application server such as Tomcat, and usually it is the server that contains the main() method which is ultimately responsible for starting up your application.
This is an example of inversion of control -- many application frameworks work this way.

You need a main() method in applications started from the command line as that's the API that the JVM expects to execute in that case. Code called from within other frameworks must implement whatever API that framework expects. In many cases that framework implements main() and calls your code via some other API. This is usually more robust than public void main(String[] args) allows. In other instances the framework is itself called from another abstraction (e.g. a Web Application within a Web Framework within a App Container).

Related

How to call a method after a object from another class is created

First of all I want to show you my diagram:
Diagram. How you can see, we have two modules "Ticket" and "Notification". The notification module depends on the ticket module. Once the "TicketService" created a ticket, the sendEmail method from the EmailHandler component shall be invoked. Unfortunately, I do not know how I can solve this.
Exists a pattern valid for any architecture. When your TicketService create a ticket, it generate an event and any interested process will subscribe.
In EJB it can be solved using #Observes annotation but any events broker (streaming... kafka, activemq, spark, ...) can be used too.
Spring Boot does not support directly event registration (like #Observes as described here) but you can use it or any other event broker.
If you are not using Java enterprise services I recommend that you use a broker according to the needs of your project (e.g. kafka if it is big or nats for simplicity).
To show a minimal code example using NATS, you can connect to a NATS server broker using:
final Connection nc = Nats.connect("nats://localhost:4222");
then, any process interested in knowing that a new ticket has been created would listen for such events
final Subscription sub = c.subscribe(CHANNEL);
while (true)
sendMessageForTicket(sub.nextMessage(Duration.ofDays(365)).getData());
the TicketService will send a message to be received by all these listening processes
c.publish(CHANNEL, myCreatedTicketData);
of course, all processes are decoupled, horizontally scalable (e.g. microservices) and only share the knowledge of the existence of a certain Ticket.
Your diagram explains the architecture (components and relations) while ignoring technical details (technologies/frameworks) In plain java. You can implement it quickly in plain java if you want.
Create two java packages for 'ticket' and 'notification' modules.
Create a java interface for EmailHandlerInterface and put it to the 'ticket' package.
Inside the 'notification' package, Create EmailHandler class and implement created EmailHandlerInterface
Inside the 'ticket' package, implement Ticket object as simple java POJO class,
Inside the 'ticket' module, create the TicketSercice class that does take the Ticket object as a prototype and returns a created Ticket object.
You need an additional object (let's name it TicketModuleExecutor or something) inside the "ticket package" . You will have to inject an EmailHandler via EmailHandleInterface to it. This object should have a method 'execute' that creates a Ticket object, passes it to the TicketService, and executes after the successful TicketService::create call EmailHandler::sendEmail via interfaces.
In the 'default' package, create the main application class with the main method (So you can execute your program). Inside the main, you initialize your 'ticket' module main class, initialize an EmailHandler object and pass it to the main course, and calls the TicketModuleExecutor.execute() to complete the whole program.
In general, if you follow all good practices like SOLID and IoC during implementation, you can later easily migrate your code to any framework without changing your architecture.
I might have made small mistakes; because it's so hard to code without coding using the English language, which is not your native language :-D
But I will not do coding for you because I don't want to solve your task for you. You should implement the app yourself.
In Spring, you first should define what a module is for you. If it is a separate independent application, then choose communication method 1. Synchronous or 2. asynchronous. For the synchronous option, you can use rests or servlets. 2. For assychronous, you can use KAFKA, RabitMQ, JMS, or any other broker.
If you want to have modules inside one application, you can use my plain java example and implement it using Spring Beans, or you can use spring events or the AOP approach. There are dozens of options for how this diagram could be implemented ;-)
Anyway, for such a simple case, I recommend KISS (keep it simple stupid) implementing the application using Spring bean objects should suffice here.

Convert Java Servlet to Standalone Java Application

I have a legacy Java servlet that is currently running in a Tomcat container. I want to run it outside the container, as a standalone Java application. The primary intention in doing so is because the new role in which this application will be deployed, involves only computation, and no servicing of requests.
How should I go about modifying the servlet code? Will pulling out the servlet's init() code into the main() method of a new class help?
Extract the functionality you want from the servlet to other classes, so that the servlet is only the web interface to the functionality.
Those other classes should ideally not use anything in javax.servlet.*.
Then create a separate class with a main method that uses those other classes, in an appropriate way.
I would transform the servlet class into a main class, as you mentioned. The main method of the new class will create an instance of main class, execute init method to initialise if (potentially using the arguments received from the command line). Then invoke the service method inside a try/catch/finally block and invoke the destroy method of the servlet inside the finally block. Of course, your new service method will be invoked without parameters and will not contain any references to the servlet api.
yes.
The servlet implements the interface to interact with the Tomcat servlet container. If there are no settings read from the servlet context (path names, configuration paramters) you can extract the logic into a main class.
You will need to make sure you do not rely on the request/response scheme in your services. Usually if only one process runs code is much easier to write than in concurrent scenarios. But one cannot be sure there will be no such effect (for example caches that are now request based will not be emptied in standalone).
also remove any servlet api dependencies in your code. It will not work and is no longer required.
good luck!
You have to do that carefully. It may happen that some filters are doing necessary work not seen within the servlet
Assuming your case is rather simple and a GET or POST just triggers the code, it should be easy to convert into a classical java application.
Just call the former init part and the code from doGet or doPost respectly.
You need to figure out a couple of things first, the functionality in the servlet will probably react to some of the url's parameters.
first figure out what the computational part is and what parameters it expects,
once you understand that, figuring out what to put in your standalone application will be trivial.
another approach is to embed Jetty in your main application and let that run your servlet,
this will leave your servlet code untouched reducing the risk of introducing bugs

Unit testing web service calls

I am working on a Java project that is split up into a web project and a back-end project. The web talks to the back-end via web service calls.
There is one class in the web project that makes all of the web service calls and I would like to add testing around this class. I want to do unit testing, and not functional testing, so I do not want to have to have the web service actually running to run the tests. If this class were simply passing the calls through to the back-end, I might be willing to overlook testing it, however there is caching happening at this point, so I want to test that it is working correctly.
When the web service is generated jax-ws wsgen it creates an interface that the front end uses. I have used this generated interface in order to create a fake object for testing. This works pretty well, but there are issues with this approach.
I am currently the only one on my team that is doing unit testing, and so am the only one maintaining the test code. I would like to be able to have the test code be built when the rest of the code is built, but if someone else introduces a new method into one of the web service classes, then the interface will have the new method on it, and my fake object will not implement it, and will therefor be broken.
The web and the back end code projects are not dependent on one another, and I do not want to introduce a dependency between them. So, introducing an interface on top of the web service endpoint does not seem plausible since if I put it in the back-end, my web code needs to reference it, and if I put it in the front-end, my back-end code needs to reference it. I also cannot extend the endpoint since this will also introduce a dependency between the projects.
I am unfamiliar with how web services work, and how the classes are generated for the web project to be able to refer to them. So, I do not know how to create an interface in the back end that will be available for me to use in the web project.
So, my question is, how would I get the interface available to my front-end project without introducing a project dependency (in Eclipse build path)? Or, is there another, better way to fake out the back-end web service that I am calling?
First off, I'd break out the caching code into a testable unit that does not directly depend upon the web service calls.
As for the web services, I find it useful to have both functional tests that exercise the web services and other tests that mock out the web services. The functional tests can help you find edge cases that your mocks may miss.
For instance, I'm using Axis2 and generating stubs from the WSDL. For the mocks, I just implement or extend the generated stubs. In our case the real web service is implemented by an outside organization. Probing their web service through exploratory functional tests has revealed some exceptions that needed to be handled that were not apparent by just examining the generated stubs. I used this information to better mock these edge cases.

Calling Java from a Java console app and an ASP.NET app

Recently I got asked to write a java application for my company. I'm a seasoned .Net developer so this is all new ground to me.
My task is to produce an invoicing application that has several high level tasks such as:
Build single invoice
Build all invoices
My company want to be able to call these tasks from a java console application - passing in relevant commands and parameters to invoke the tasks. They also want to be able to invoke the same code from an ASP.NET application.
Therefore my first thought was to use Web Services in Java.
My question is: Can I use Web Services in Java from both a Java Console Application and from an ASP.NET application? Or perhaps are there better alternatives.
Any pointers to get me researching in the right direction would be appreciated.
Thanks.
"My company want to be able to call these tasks from a java console application - passing in relevant commands and parameters to call the tasks. They also want to be able to call the same code from an ASP.NET application."
I'm not sure exactly what you are asking, but I think the simple answer is to ensure that your application has an entry point method so that it can be run as a command line applications. You need a class with a method that looks like this:
package foo.bar;
public class Bazz {
...
public static void main(String[] arguments) {
// parse the arguments and run the application
...
}
}
The signature of the main method is critical:
it must be public static,
it must have the name main,
it must tack a single String[] argument and,
it must have a void return type.
This command can then be run from the command line as follows:
java -cp <YOUR_CLASS_PATH> foo.bar.Baz arg1 arg2 ...
This can also be done by another application written in Java, and (I imagine) from ASP.NET as well.
The simple answer is - yes. Java has libraries for defining Web Services and deploying them, and both Java and .NET have utilities for generating Web Service clients. That's not to say it will be easy though!
If I was you, I would instead investigate creating a REST service using a JAX-RS implementation (my favourite is RestEASY). This will allow you to create a 'web service' without SOAP, i.e. http://server/invoices/1 might return
<invoice>
<items>
<item>apple</item>
<item>banana</item>
<items>
<customer>robert</customer>
<amount>5.00</amount>
</invoice>
Which it then should be easy to interpret in any language. Either way it will be a steep learning curve though. The main difference between Java and .NET is that while a lot of functionality is built in to .NET, in Java it's spread across the ecosystem, which is good because it provides variety, however it can take a bit longer to locate functionality.

Running servlet class from another class

I just got a servlet class working in Eclipse. I was testing it by deploying it using App Engine, and it would prompt me to run as a Web Application. Now I want to run this code from another class. So I made another class and put "TestServlet ts = new TestServlet();" in the main function. When I run it nothing happens. Do I have to make a call to the TestServlet's "doGet" method, or is it something to do with not running the main class as a web application?
Umm... you should not be doing this. Extract common logic into a separate POJO (plain old java object) class and invoke it from both your servlet and your other class.
Manually instantiating / invoking servlets is NOT a good idea.
You need a servlet container if you want to run it up for real. I would suggest using Winstone http://winstone.sourceforge.net. It's a small, fast, zero-config container for getting your servlet up and running.
Calling doGet (or doPost or any other visible method) in the instance of the servlet object will execute the containing code. However be aware that behaviour may differ from running the servlet in an web container if the code makes use of any of the "wired-in" context variables.
At face value I would suggest you refactor to have the code you require in a common method and call from both your servlet and your main class.

Categories

Resources