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.