grailsgroovygrails-3.0.9

Inject services to src/groovy in Grails 3.0.9


I am trying to create an EndPoint file. So I created a file with name ServerEndPointDemo.groovy

package com.akiong

import grails.util.Environment
import grails.util.Holders

import javax.servlet.ServletContext
import javax.servlet.ServletContextEvent
import javax.servlet.ServletContextListener
import javax.servlet.annotation.WebListener
import javax.websocket.EndpointConfig
import javax.websocket.OnClose
import javax.websocket.OnError
import javax.websocket.OnMessage
import javax.websocket.OnOpen
import javax.websocket.Session
import javax.websocket.server.PathParam
import javax.websocket.server.ServerContainer
import javax.websocket.server.ServerEndpoint
import javax.websocket.EncodeException

import javax.servlet.annotation.WebListener
import java.util.concurrent.CopyOnWriteArraySet

@WebListener
@ServerEndpoint(value="/chat/test/{username}")

public class ServerEndPointDemo implements ServletContextListener {
    private static HashMap<String, String> usersMap = new HashMap<String, String>();
    private static final Set<ServerEndPointDemo> connections = new CopyOnWriteArraySet<>();
    private String username
    private Session session

    @OnOpen
    public void  handleOpen(Session session,@PathParam("username") String user){
        System.out.println("-------------------------------------");

        System.out.println(session.getId() + " has opened a connection");
        println "user = "+user

        connections.add(this);
        this.username   = user
        this.session    = session

        addUserToMap(username,session.getId())

        try{
            def ctx = Holders.applicationContext
            chatService = ctx.chatService
        }
        catch (Exception e){
            println "e = "+e
        }

    }

    @OnClose
    public void  handleClose(Session session){  
        System.out.println("Session " +session.getId()+" has ended");  
    }

    @OnMessage
    public String handleMessage(String message,Session session){
        chatService.saveSessionAdminJava(session.getId())    
    }

    @OnError
    public void  handleError(Throwable t){
        println "error ~"
    }  

    private void sendMessageToAll(String message){
        println "session.size() = "+sessions.size()
        for(Session s : sessions){
            try {
                s.getBasicRemote().sendText(message);
                println "sent to session = "+s.getId()
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
`

I tried to use this code for calling a method from service:

try {
    def ctx = Holders.applicationContext
    chatService = ctx.chatService
} catch (Exception e) {
    println "e = " + e
}

This is my service:

package com.akiong.services

import com.akiong.maintenance.Chat

class ChatService {

    def serviceMethod() {

    }

    def saveSessionAdminJava(def sessionJava) {
        println "jaln!!!"
        def chatInstance = Chat.findByIsAdmin("1")
        chatInstance.sessionJava = sessionJava
        chatInstance.save(failOnError: true)
    }
}

But after I tried to run this code, I'm getting this error:

Error : groovy.lang.MissingPropertyException: No such property: chatService for
class: com.akiong.ServerEndPointDemo

Anyone know how to call a method from service to file in src/groovy?


Solution

  • So here is the problem. The code you written is correct for injecting service:

    try {
        def ctx = Holders.applicationContext
        chatService = ctx.chatService
    } catch (Exception e) {
        println "e = "+e
    }
    

    But the chatService is not defined anywhere in your class. So even if your handleOpen method is invoked there must be MissingPropertyException being thrown but since you have handled the top level Exception class (which should never be encouraged) that exception from your handleOpen method got suppressed.

    Now, later in your handleMessage method, the same problem is occurring again of chatService being undefined and hence you are getting the exception you posted in your question.

    So, you know the answer now :-) Simply define the chatService in your ServerEndPointDemo class.

    Update:

    public class ServerEndPointDemo implements ServletContextListener {
        private static HashMap<String, String> usersMap = new HashMap<String, String>();
        private static final Set<ServerEndPointDemo> connections = new CopyOnWriteArraySet<>();
        private String username
        private Session session
    
        def chartService    // Initialize here
        // rest of your code
    }