I'm working on modifying an existing application implemented as a 2.1 stateless EJB. I'd like to put in some kind of generic, detailed, logging of all calls made to the EJB.
Stuff I'd like to log:
Name of method being called
Serialized copy of all passed parameters
Serialized copy of return value
I implemented something like that for an asp.net REST web service before by simply putting in a hook before the request is processed and one right before the response is sent back. It produces a lot of data, but it's well worth it for debugging a long running system.
I'm not sure how the same can be done for an EJB. I'd like to avoid AOP since the application doesn't currently use AOP. Interceptors won't work because it's not EJB 3.0.
Does anyone know of a way to hook into the EJB processing pipeline to look at request as they come in? Is there another approach to doing this?
Thanks
I think there are only two ways two ways to know when a method of an EJB (or any other class) is called:
Bad solution: using the Java Debug Interface (JDI) you can know which line is executed, as you know it when you are debugging Java with your IDE. It's complicated and there are some problems when you are debugging an application in the same JVM where JDI runs.
Good solution: as Thomas Owens says, AOP is the recommended solution. If you are not using it in your project now, this is a good reason for using it.
Related
I want to develop a service that exposes a rest API to upload plugins and the plugins are locally executable, i.e. other classes from the server use them.
The plugins also:
The plugin should be a jar file that is submitted through the REST API and once is validated, is then made available through another API method to see the metadata and to execute.
Are not too complex (they should all contain at least a a class that extends of an abstract class or an interface implementation of an interface, the service) but could have their own dependencies.
The API allows to validate that the plugin is compliant with the service and that it declares some additional information on an XML or JSON file contained on the JAR.
Have some metadata that has to be exposed through the API (Version, who made it, is it usable, what data can it be handled) in Json form.
All implement an algorithm to perform some data crunch so they all have something like an execute() method. The result of executing this method is handled to another class, so is not totally important to expose it on the API.
Must be able to be uploaded and executed by the other server classes in runtime, so no restart is possible
The thing is that I am not sure where to start, since I had already developed some of the basic API on Spring-boot since it had all the things I needed to easily develop a REST API but the more I read about how to dynamically load modules (plugins) the more I see that Spring does not support this ind of thing and I am not sure a class loader or Service loader would work in that context.
I found out about OSGi framework but I honestly do not know it changing the whole technology stack will help me so I want to make sure it is the right answer, and if yes, then find some resources that point me in the right direction, e.g. some tutorial that implements something similar.
Thank you for any advice.
Checkout OSGi enRoute. It includes a model to developing RESTful services: http://enroute.osgi.org/services/osgi.enroute.rest.api.html.
OSGi sounds like the best match to what you try to do.
You can install everything as a bundle including your main application. Nowadays this is much less work than some years before but still not to be underestimated.
The other option is to start an embedded OSGi framework where you just install your plugins. This is less work but you need to know exactly how it works.
So for both cases I suggest to get help from an external OSGi expert as it speeds up the transition a lot and avoids many wrong paths you will choose as a beginner.
I am starting to learn about EJB, despite I know they handle the business logic, I don't understand why an EJB has to implement an interface.
I know that the interface is a list of the methods and is used by the client to access them, but what if I don't use an interface?
I know that the no-interface view exist but when should I use an interface then?
could you please explain it using a no IT example? I am taking a course about Java EE 7 and I am stuck in this part, I have read the Oracle tutorial but I've got problems understanding this.
I apologize for my wording mistakes.
thanks in advance
The reason for an interface is because you need to invoke a method in one JVM that transparently can invoke your EJB in another JVM. All the complexity of Java EE come from that it is designed to work across multiple JVMs.
This can be handled in many ways. The approach chosen here is that an interface can make this almost transparent in your code (just compare with invocation through reflection) but the object in the first JVM contains not your code, but instead code that knows how to reach the other JVM and ask it to invoke your method and return the result.
In other words, an interface allows the compiler to help you doing it right in your code, and the application server then provides the magic glue in the object called to reach your EJB.
An EJB doesn't have to implement an interface (anymore). Well, this is only true, if you haven't different VMs accessing the same EJB container. You could host your JBoss in the cloud (e.g.) and have another JEE-Server (e.g. Tomcat) at your company site (or anywhere else) and let the TomEE retrieve its EJB instances from the JBoss Application Server. Then you have to use an interface to program against, since you don't know what the implementation will be.
Since EJB 3 no-interface views are possible. You're free to use interfaces, but you shall be happy if you don't... as long as you dont need distributed EJB-services.
An interface is always a great choice, when you design a big system though. You can easily change you underlying logic if you program against the interface and not the concrete class. So if specifications change, code is much easier to maintain.
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
I've searched on internet and here on SO, but couldn't wrap my mind around the various options.
What I need is a way to be able to introduce customer specific customization in any point of my app, in an "external" way, external as in "add drop-in jar and get the customized behavior".
I know that I should implement some sort of plugin system, but I really don't know where to start.
I've read some comment about spring, osgi, etc, can't figure out what is the best approach.
Currently, I have a really simple structure like this:
com.mycompany.module.client.jar // client side applet
com.mycompany.module.server.jar // server side services
I need a way of doing something like:
1) extend com.mycompany.module.client.MyClass as com.mycompany.module.client.MyCustomerClass
2) jar it separately from the "standard" jars: com.mycompany.customer.client.jar
3) drop in the jar
4) start the application, and have MyCustomerClass used everywhere the original MyClass was used.
Also, since the existing application is pretty big and based on a custom third-party framework, I can't introduce devastating changes.
Which is the best way of doing this?
Also, I need the solution to be doable with java 1.5, since the above mentioned third-party framework requires it.
Spring 3.1 is probably the easiest way to go about implementing this, as their dependency injection framework provides exactly what you need. With Spring 3.1's introduction of Bean Profiles, separating concerns can be even easier.
But integrating Spring into an existing project can be challenging, as there is some core architecture that must be created. If you are looking for a quick and non-invasive solution, using Spring containers programmatically may be an ideal approach.
Once you've initialized your Spring container in your startup code, you can explicitly access beans of a given interface by simply querying the container. Placing a single jar file with the necessary configuration classes on the classpath will essentially automatically include them.
Personalization depends on the application design strongly. You can search for a pluggable application on the Internet and read a good article (for an example: http://solitarygeek.com/java/a-simple-pluggable-java-application). In the pluggable application, you can add or remove a feature that a user decides. A way for the pluggable application is using the Interface for de-coupling of API layer and its implementation.
There is a good article in here
User personalisation is something which needs to be in the design. What you can change as an after thought if the main body of code cannot be changed, is likely to be very limited.
You need to start be identifying what can be changed on a per user basis. As it appears this cannot be changed, this is your main limiting factor. From this list determine what would be useful to change and implement this.
Say you have an application with a series of actions. How would you write it such that actions are logged when they are triggered?
Use a Template pattern.
Use AOP.
Use a Listener and Events.
Use a combination of the above.
Something else (explain).
I'd vote for AOP for the sake of eliminating redundancy, but only if there's room for AOP in your project.
You can have custom logging using a logging library from your methods elsewhere in your project, but in a particular component where you hold many similar classes and want to log similar things for all of them, it can be painful to copy/paste and make sure everyone knows how to log.
EDIT: regarding the other enumerated approaches, I think the advantage of AOP would be that it doesn't require you to design your code (template methods or events) specifically for this topic. You usually don't lose any of the code flexibility when spotting cross-cutting concerns and treating them as such, as opposed to redesigning a whole class hierarchy just to make use of consistent logging.
I think the best answer is using log4j (or sli4j, if that's the latest) inside an aspect.
Logging is the "hello world" of AOP. If you aren't using AOP, you're doing it wrong.
It really would depend on your specific context. Specifically on what was being tracked and how the application currently worked. If the actions are classes that all have a common base class and all you care about is the name of the action, then a simple addition to log in this class would be a great choice. If you have actions spread across several layers of code, then an AOP or Listener/Event type solution might work better. If that application was a web app vs desktop or if you ultimately need the logs feed to a database, webservice, or just want text files all make a difference.
if you simply want to log particular actions it's probably simplest to use a logging api such as commons-logging or log4j etc add a log statement in the code you wish to track.