简体   繁体   中英

Spring boot autowired service all variable fields are null

Currently I have many spring boot services annotated with @Service. Every service works fine and there are no problems. There is a problem only with LogsService. LogsService is implemented the same way as other services such as StaticPageService.

In order to log in a user must use method "onLoginClicked" from LoginViewModel class. LoginViewModel class:

package com.flyingdynamite.jvmbackend.views.login

import com.flyingdynamite.jvmbackend.data.constants.LogCategory
import com.flyingdynamite.jvmbackend.extensions.isNotNull
import com.flyingdynamite.jvmbackend.security.hash.Hash
import com.flyingdynamite.jvmbackend.service.AdminAuthorizationService
import com.flyingdynamite.jvmbackend.service.LogsService
import com.flyingdynamite.jvmbackend.service.UserModelService
import com.flyingdynamite.jvmbackend.util.SystemInformation
import com.flyingdynamite.jvmbackend.util.base.validation.Argon2PasswordHash
import com.flyingdynamite.jvmbackend.util.generator.ApiAccessCredentialsGenerator
import com.flyingdynamite.jvmbackend.util.generator.TextIdGenerator
import com.flyingdynamite.jvmbackend.views.AdminPanelRoute
import com.flyingdynamite.jvmbackend.views.BaseViewModel
import com.flyingdynamite.jvmbackend.views.dashboard.DashboardView
import kotlinx.coroutines.*
import org.apache.commons.lang3.RandomStringUtils
import org.apache.commons.lang3.time.StopWatch
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.config.ConfigurableBeanFactory
import org.springframework.context.annotation.Scope
import org.springframework.stereotype.Component
import org.springframework.util.unit.DataSize
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.*
import java.util.concurrent.TimeUnit

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
open class LoginViewModel : BaseViewModel() {

    private val TAG = "LoginViewModel"

    @Autowired(required = true)
    private lateinit var logsService: LogsService

    @Autowired(required = true)
    private lateinit var userModelService: UserModelService

    @Autowired(required = true)
    private lateinit var adminAuthorizationService: AdminAuthorizationService


    private var loginJob: Job? = null
    private var developerTasksJob: Job? = null

    init {

        viewModelScope.launch {
            setPageTitle("Login")
        }
    }

    override fun onCleared() {
        loginJob?.cancel("onCleared")
        developerTasksJob?.cancel("onCleared")
    }

    //    @PostConstruct
    private fun runScheduledDeveloperTask() {
        logger.warn("runScheduledDeveloperTask")
        if (productionMode) {
            return
        }
        Timer(TAG).schedule(object : TimerTask() {
            override fun run() {
                logger.warn("runDeveloperComputationTask")
                runDeveloperComputationTask()
            }
        }, Date.from(LocalDateTime.now().plusHours(6).atZone(ZoneId.systemDefault()).toInstant()))
    }

    fun onLoginClicked(login: String?, password: String?) {

        if (loginJob != null) {
            return
        }

        loginJob = computationViewModelScope.launch {
            logsService.enqueue(TAG, LogCategory.INFO, "onLoginClicked / login _> ${login} / password _> ${password}")
            println("$TAG -> onLoginClicked / login _> ${login} / password _> ${password}")
            setIsLoading(true)
            setErrorText(null)

            val inputValuesErrorText = inputValuesErrorText(login, password)
            println("$TAG -> onLoginClicked / inputValuesErrorText _> ${inputValuesErrorText} / isEmpty _> ${inputValuesErrorText.isEmpty()}")

            val authorized = adminAuthorizationService.isAuthorized(login!!, password!!)

            val resultError = if (inputValuesErrorText.isNotNull()) {
                inputValuesErrorText
            } else {

                if (authorized) null else localizedTexts.getOrEmpty("wrong_credentials")
            }
            println("$TAG -> onLoginClicked / resultError _> ${resultError}")
            setErrorText(resultError)
            delay(100)
            setIsLoading(false)

            setNavigateTo(
                    if (authorized) Triple(
                            DashboardView::class.java,
                            AdminPanelRoute.DASHBOARD,
                            userModelService.getUserByUsernameOrThrow(login)
                    ) else null
            )
            loginJob = null
//            setNavigateTo(null)
        }
    }

userModelService and adminAuthorizationService have no issues.

LogsService class:

package com.flyingdynamite.jvmbackend.service

import com.flyingdynamite.jvmbackend.data.constants.LogCategory
import com.flyingdynamite.jvmbackend.data.model.LogItem
import com.flyingdynamite.jvmbackend.repository.jpa.LogsJpaRepository
import com.flyingdynamite.jvmbackend.service.exception.NotFoundException
import com.flyingdynamite.jvmbackend.util.AppInfo
import com.flyingdynamite.jvmbackend.util.LogUtils
import com.vaadin.flow.server.WebBrowser
import kotlinx.coroutines.*
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.config.ConfigurableBeanFactory
import org.springframework.context.annotation.Scope
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.Duration
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.*
import java.util.concurrent.TimeUnit
import javax.persistence.EntityManager
import javax.persistence.EntityManagerFactory
import javax.persistence.PersistenceContext
import javax.persistence.criteria.CriteriaBuilder
import javax.persistence.criteria.Predicate
import java.util.concurrent.ConcurrentLinkedQueue

@Service
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
open class LogsService : BaseService() {

    private val TAG = "LogService"

    @Autowired(required = true)
    private lateinit var appInfo: AppInfo

    @Autowired(required = true)
    private lateinit var logRepository: LogsJpaRepository

    @Autowired(required = true)
    @PersistenceContext
    private lateinit var entityManager: EntityManager

    @Autowired(required = true)
    private lateinit var entityManagerFactory: EntityManagerFactory


    private val queue: ConcurrentLinkedQueue<LogItem> = ConcurrentLinkedQueue<LogItem>()

    private val cmdLog: Logger by lazy {
        LoggerFactory.getLogger(this::class.java)
    }

//    private val queue: ConcurrentLinkedQueue<LogItem> by lazy {
//        ConcurrentLinkedQueue<LogItem>()
//    }

    private var deleteOlderDays: Int = 30
    private var insertMinLogItemsCount: Int = 100
    private var insertMaxSecondsDifference: Int = 5

    private var isActive: Boolean = true

    private var queueJob: Job? = null

    private val terminatingMessage: String = "TERMINATING !"

    private var displayInCMD: Boolean = true

    @Synchronized
    fun enableDisplayInCMD() {
        displayInCMD = true

        if (isActive) {
            startQueueThreadIfPossible()
        }
    }

    @Synchronized
    fun disableDisplayInCMD() {
        displayInCMD = false

        if (isActive) {
            startQueueThreadIfPossible()
        }
    }

    @Synchronized
    fun activate() {
        if (displayInCMD) {
            cmdLog.trace("activating _ !")
        }
        isActive = true

        startQueueThreadIfPossible()
    }

    @Synchronized
    fun deactivate() {
        if (displayInCMD) {
            cmdLog.warn("DEACTIVATED _ ! ")
        }
        onCleared()
    }

    @Synchronized
    fun onCleared() {
        isActive = false
        queueJob?.cancel("onCleared")

        queueJob = serviceScope.launch {
            delay(TimeUnit.SECONDS.toMillis(2))

            if (displayInCMD) {
                cmdLog.warn("inserting queue all remaining items -> ${queue.size} ")
            }

            insertList(queue.toList())
            queue.clear()
            queueJob = null
        }
    }
}

BaseService class:

package com.flyingdynamite.jvmbackend.service

import com.flyingdynamite.jvmbackend.extensions.FD_CPU_INTENSIVE_LIMITLESS
import com.flyingdynamite.jvmbackend.extensions.FD_IO_LIMITLESS
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers


open class BaseService() {

    protected val serviceScope:CoroutineScope =  CoroutineScope(Dispatchers.FD_IO_LIMITLESS)

    protected val serviceComputationScope: CoroutineScope = CoroutineScope(Dispatchers.FD_CPU_INTENSIVE_LIMITLESS)

    protected fun onException(e: Exception) {
        println("[Exception] -> ${e.message}")
        e.printStackTrace()
    }

}

When user executes onLoginClicked this error occurs:

Exception in thread "pool-2-thread-1" java.lang.NullPointerException
    at com.flyingdynamite.jvmbackend.service.LogsService.enqueue(LogsService.kt:171)
    at com.flyingdynamite.jvmbackend.service.LogsService.enqueue(LogsService.kt:162)
    at com.flyingdynamite.jvmbackend.views.login.LoginViewModel$onLoginClicked$1.invokeSuspend(LoginViewModel.kt:81)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)

LogsService.kt:171 -> queue.offer(log) in method enqueue from LogsService class.

If I change the code and execute for example something with serviceScope variable the same error occurs. Then serviceScope is null. Every variable inside LogsService is null when I am trying to use it. Please help mi with this. Where is the mistake?

Resolved. Issue was in the logs but only when logging.level.root=DEBUG was set in application.properties

After long search this was somewhere in the logs:

cannot get proxied via CGLIB: Calls to this method will NOT be routed to the >target instance and might lead to NPEs against uninitialized fields in the >proxy instance.

After adding "open" to every method of LogsService class - log entry is not displaying anymore. Seems it is fixed. Not getting any NPE anymore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM