Packaging embedded tomcat server - java

First time ever using tomcat/setting up a webapp from scratch so please be mercyful. I have created an embedded tomcat server which basically looks like this:
public class Server implements Runnable {
private Tomcat tomcat;
public Server() {
tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.addWebapp("", new File("src/webapp").getAbsolutePath());
}
#Override
public void run() {
try {
tomcat.start();
tomcat.getServer().await();
} catch (LifecycleException e) {
e.printStackTrace();
}
}
And I run it in a main that looks like this:
public static void main(String[] args) throws Exception {
Thread thread = new Thread(server);
thread.start();
Foo foo = new Foo();
(thread.isAlive()) {
foo.doStuff();
TimeUnit.HOURS.sleep(interval);
}
}
The purpose of the program is to run the http-server on one thread while the class Foo does some stuff in the backend once every so-and-so hours. Probably not the correct way to create a webapp, but it's the best I've managed.
However, now that I'm trying to package it I'm running into issues because once it is packaged (using Maven) the Server doesn't seem to be able to find the webapp-folder. After a couple hours of googling and trying out a a lot of stuff involving war:s and jar:s I've come to the conclusion that there is something about this embedded tomcat stuff that I'm not understanding.
So, my questions are:
Is the way I've implemented my webapp correct? I'm getting the feeling that it's not but I can't really confirm it.
2a. If incorrect, how does one do it correctly?
2b. If correct, how does one package it into a runnable jar/war?

This is a little bit of a non-standard way of going about it. Rather than writing all your own application logic to handle an integrated web server, would you not consider leveraging something that's already there? You can create a Java project in Spring boot which contains its own embedded web server.
There's a sample starter example here that should get you going - https://spring.io/guides/gs/serving-web-content/
I would recommend this approach rather than writing it yourself as Spring Boot is an industry standard that is widely used, proven, and tested.

Related

In a Spring-Boot application without web server, what is the correct way to keep it running?

I have written a small spring-boot application without embedded servers. It is intended to run from command line and stay running until the VM gets signalled. What is the intended way of in the spring-boot framework (v2.0) to keep the application alive as a service? Should I have a Thread.currentThread().wait(); as last statement in my run(ApplicationArguments args) method? Is there an enabling annotation?
from org.springframework.boot.web.embedded.netty.NettyWebServer, Official.
private void startDaemonAwaitThread(DisposableServer disposableServer) {
Thread awaitThread = new Thread("server") {
#Override
public void run() {
disposableServer.onDispose().block();
}
};
awaitThread.setContextClassLoader(getClass().getClassLoader());
awaitThread.setDaemon(false);
awaitThread.start();
}

JAX-RS: Server-side user interface

I have a JAX-RS REST service which needs to provide some visual server side output when a REST endpoint is invoked. Later on, I might also want to provide a user interface which an administrator will use for interacting with the web service. I could obviously build REST endpoints for this interaction, and have the administrator invoke these (from a different machine or the same machine) using a provided client application with a UI, but I would like to avoid exposing this functionality to the network. In order to make deployment easy, I would also like everything (i.e. the web service and its administrator UI) to be part of the same application.
I have found that my JAX-RS application will throw a HeadlessException if I try to construct a JFrame or any other top level UI element as described here. I have also found that I can avoid this by setting the system property -Djava.awt.headless=false.
I think I may be able to achieve what I need by setting the headless system property as above and defining a singleton startup EJB that will handle all server side UI tasks:
#Singleton
#Startup
public class UiBean {
private JFrame frame;
#PostConstruct
public void init() {
SwingUtilities.invokeLater(() -> {
frame = new JFrame();
// ...setup UI...
});
}
// JAX-RS resources will inject the UiBean and invoke methods as this one when UI updates are needed.
public void updateSomeUiComponent() {
SwingUtilities.invokeLater(() -> { ... });
}
}
I realise that this design is not ideal. Are there other ways of achieving my requirements? The software being built is a prototype and time is of the essence, so I would like to avoid having to learn complete new technologies (already invested a lot in learning JAX-RS and JPA). Quick-and-dirty is ok, I guess I'm just looking for the least dirty solution ;).
Thanks in advance!

wildfly have a ever running process run in the background

I'm making a html5/js game that will have online capabilities for my backend I've decided to use a wildfly server. The client will communicate with the server via web sockets.
I intended for my wildfly server to also be in charge of game logic decisions such as moving npc's. My plan was to have a #startup bean that would run a server game loop to handle this logic. The server loop would then talk to the serverEndPoint via HornetQ. My serverEndPoint and server loop look like this:
ServerEndPoint
#ServerEndpoint(value= "/game/{user-id}")
public class GameEndpoint {
#Inject
GameManager gameState;
GameWorld gameWorld;
Player p;
private Logger logger = Logger.getLogger(this.getClass().getName());
#OnOpen
public void onOpen(Session session){
//do stuff
}
#OnMessage
public void onMessage(Session session, String message){
//do stuff
}
#OnClose
public void onClose(CloseReason reason){
//do stuff
}
#OnError
public void error(Throwable t){
//do stuff
}
}
GameWorld
#Startup
#Singleton
public class GameWorld {
#Inject
GameManager gameState;
private Logger logger = Logger.getLogger(this.getClass().getName());
#PostConstruct
public void init(){
gameloop();
}
private void gameloop(){
while(true){
logger.info("This is a test!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#PreDestroy
public void terminate(){
//do stuff
}
}
the issue with this is that the server loop freezes everything as it is a infinite loop(for instance if I try and access the html web page I get a 404). obviously this could be solved if the serverLoop was on its own seperate thread but after doing some research it seems threading in jboss is very difficult as its hard to know what dependencies to inject e.t.c
Can anyone shed some light on how I can solve this issue? any help on the matter would be amazing.
What you have encountered has to do with what Java EE is and what it not is: Java EE is optimized for handling many concurrent, short-lived requests, each of which (usually) handle a single transaction. The containers do that very well, particularly with stateless beans, but also with stateful beans (cluster replication etc). As such, Java EE might be well-suited to process the requests coming from your HTML5/JS clients and feed the requests to the messaging infrastructure. Java EE is not, however, designed for long running, thread-blocking background processes like yours.
FWIW: Another issue that you have not yet encountered is, even if you could get that one fixed: Next you'll encounter the transaction timeout on your #PostConstruct method.
I think you are better of with moving the game engine out of the Java EE stack. You already mentioned you plan to use HornetQ - then why not put the game engine in a simple standalone application that receives messages from HornetQ and feeds replies back into HornetQ.
Another option might be a dedicated Java game server engine, see, e.g., this question and its accepted answer on programmers.stackoverflow.com. (Update: it seems the "RedDwarf Server" project mentioned in that answer was discontinued 3 years ago).
If you absolutely want to use the Java EE environment, I suggest you use a TimerService instead. Note, however, that this also requires that your game loop calculation is quick and guaranteed to finish until the next timeout is scheduled, otherwise the container will skip the scheduled invocation (with a "still running" message or similar).
Finally, let me mention that if I were to start a new game server today, I would definitely take a look at Akka, Node.js or similar projects that support "reactive" programming.

Getting 2 Tomcat servers comminicating with each other

I have a Java web application I’m developing for a school project. There’s a requirement to have the presentation tier (servlets/jsp) be deployed to one server and business logic be deployed to another.
I need a solution to connecting the 2 servers.
Currently I’ve researching RMI and Axis2.
I’m not able to get RMI successfully working. I’m following official tutorial and keep getting a security exception locally, and imagine that it will get worse when Tomcat is involved.
Axis2 seems like a good solution, but I will need time to ramp up on it.
My question is: there a simple way of connection 2 servers so that I can call my business layer? Maybe Tomcat has something built-in.
If RMI is the de-facto protocol and API I should use, is there any good tutorials on using RMI with Tomcat.
Servers that I’m using are both running Tomcat.
I am not sure how complicated is your data layer but you can implement REST interface on business logic server using Apache CXF, for example. That should be easier than using Axis2.
There are many many options:
Write a file from one side, read it from the other. "the other" has to have an infinite loop to monitor the folder where "one side" writes request files.
Use sockets
Use REST
RMI
If you're on Linux:
Shared memory
Pipes
Given your environment I would go with REST.
I ended up using RMI. Using this tutorial I got it working: http://sacrosanctblood.blogspot.com/2008/11/rmi-tutorial-rmi-and-tomcat.html . The key is: in the start up servlet you have to make sure that the Object that you are stubbing out is class scoped and not method scoped. Also, the Security manager code is not needed.
Here's the code for the startServer servlet that I'm using:
public class startServer extends HttpServlet
{
public static boolean isRegistered = false;
public IRemote service = new RemoteImpl();
#Override
public void init(ServletConfig config) throws ServletException
{
super.init(config);
if (!isRegistered)
{
try
{
IRemote stub = (IRemote) UnicastRemoteObject.exportObject(service, 0);
Registry registry = LocateRegistry.createRegistry(9345);
registry.rebind(IRemote.serviceName, stub);
System.out.println("Remote service bound");
isRegistered = true;
}
catch (Exception e)
{
System.err.println("Remote service exception:");
e.printStackTrace();
}
}
}
}
And here's the client code:
public String getRemoteString()
{
String result = "";
try
{
Registry registry = LocateRegistry.getRegistry(9345);
IRemote serv = (IRemote) registry.lookup(IRemote.serviceName);
result = serv.executeRemote("Test");
}
catch (Exception e)
{
System.err.println("Remoteservice exception:");
e.printStackTrace();
}
return result;
}
Currently it's running all on the same server, but I'm sure that I can get the 2 working at a later time.

Simplest remoting server using Spring HttpInvoker

For (JUnit) testing purposes I'd like to make a simple application that would be the server to be invoked using Spring HttpInvoker. I don't want to make a real webapp to be deployed in any servlet container, only something standalone.
Do you have any ideas how to make it as simply as possible? (Solutions without embedded Tomcat or stuff are preferred..)
This will work out well for you - http://docs.codehaus.org/display/JETTY/ServletTester
#BeforeClass
public static void initServletContainer() throws Exception {
tester = new ServletTester();
tester.setContextPath("/");
tester.addServlet(DummyServlet.class, "/dummy");
baseUrl = tester.createSocketConnector(true);
tester.start();
System.out.println(baseUrl);
}
You can start up the server in your #BeforeClass method, record the baseUrl where the server starts up and use this url to test your client.
http://code.google.com/p/jianwikis/wiki/SpringHttpRemotingWithEmbeddedJettyServer

Categories