'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 ?
Solution 1:[1]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Reckos |