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)
1
  • Create the DBConnection in the addItem method and then close it before returning. This will be less expensive if you use a connection pool. Commented Dec 2, 2014 at 14:21

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.