0

I have a simple REST service set up that is receiving data from another service and putting it into database. I planned to run it as a jar file that contains the service and the server. Code I have is:

public class Main {
    public static void main(String[] args) throws IOException {
        ResourceConfig config = new DefaultResourceConfig(MyResource.class);
        HttpServer server = HttpServerFactory.create("http://localhost:8080/", config);
        server.start();
        // ...
    }

MyResource

@Path("/rest")
public class MyResource {

    public MyResource(){
        dbConnection = new DbConnection();
    }

    private final DbConnection dbConnection;

    @POST
    @Path("/post")
    @Consumes(MediaType.APPLICATION_XML)
    public Response addItem(MyItem dao){
        dbConnection.addItem(dao);
        return Response.status(200).build();
    }

In DbConnection, the MysqlDataSource in constructor and once it gets an item, it put's it into a blockingQueue, another thread is listening and handles writing to DB.

Now the problem is, that everytime a new request is received, the MyResource is recreated, constuctor is called, hence again initiating also DbConnection class and all that comes with it. How to avoid it? It results in:

com.sun.jersey.api.container.MappableContainerException: java.lang.OutOfMemoryError: unable to create new native thread
        at com.sun.jersey.server.impl.resource.PerRequestFactory$PerRequest._getInstance(PerRequestFactory.java:189)
        at com.sun.jersey.server.impl.resource.PerRequestFactory$AbstractPerRequest.getInstance(PerRequestFactory.java:144)
        at com.sun.jersey.server.impl.application.WebApplicationContext.getResource(WebApplicationContext.java:239)
        at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:83)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
        at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542)
Caused by: java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:714)
        at myPackage.Db.DbConnection.<init>(DbConnection.java:61)
        at myPackage.MyResource.<init>(MyResource.java:21)
        at sun.reflect.GeneratedConstructorAccessor19.newInstance(Unknown Source)
Exception in thread "Thread-2" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:714)
        at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:949)
        at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1371)
        at sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:433)
        at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:398)
        at java.lang.Thread.run(Thread.java:745)
Erki M.
  • 5,022
  • 1
  • 48
  • 74
  • Create the DBConnection in the addItem method and then close it before returning. This will be less expensive if you use a connection pool. – mikea Dec 02 '14 at 14:21

1 Answers1

1

Annotate your resource class as @Singleton See also this answer When to use @Singleton annotation of Jersey?

Community
  • 1
  • 1
Shmil The Cat
  • 4,548
  • 2
  • 28
  • 37