ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> listMap = new ArrayList<>();
...
List<MyDto> testDtoList =
mapper.convertValue(listMap, TypeFactory.defaultInstance().constructCollectionType(List.class, MyDto.class));
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> listMap = new ArrayList<>();
...
List<MyDto> testDtoList =
mapper.convertValue(listMap, TypeFactory.defaultInstance().constructCollectionType(List.class, MyDto.class));
legacy 프로젝트를 maven으로 바꾸면서 properties 파일이나 mybatis xml 파일을 찾지 못하는 현상이 있었다.
Caused by: java.io.FileNotFoundException: class path resource [applicationResources.properties] cannot be opened because it does not exist
기존 프로젝트는 resourse 디렉토리가 따로 있는 게 아니라, 여기 저기 중구난방으로 되어 있다.
maven에서 아래의 설정을 추가하면 된다.
<resources> <resource> <directory>src</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> </resources>
java에서 쉘스크립트를 실행하는 기능을 추가 했다.
문제는 자바 프로그램이 종료되면 쉘스크립트 역시 1~2초 후에 멈춰 버린다.
쉘스크립트는 while true로 무한루프로 실행이 되는 스크립트였다.
자바에서 실행 명렁어를 nohup, &, sh -c 등 이것 저것 다 해 보았지만 쉘스크립트는 멈췄다.
결국 찾은 방법은 두가지이다. 두가지 방법 다 정석적인 해결책은 아니고 trick으로 볼수 있는 방법이다.
하나는 중간 launch 스크립트를 두는 방식이다.
실제 내가 실행해야 할 스크립트가 target.sh 이면 launcher.sh를 둬서 자바에서는 launcher.sh를 실행하는 방법이다.
launcher.sh에는 아래와 같은 명령을 넣는다.
#/bin/sh
nohup ./target.sh 1> /dev/null 2>&1 &
다른 하나는 trap을 사용한 방법이다.
trap 명령어는 특정 시그널이 들어올 때 어떤 일을 할 지 적용할 수 있다.
실제 적용한 방법은 두번째 방법으로 trap명령어를 통한 방법이다.
적용 방법은 아래와 같다.
trap "method_name" 0
0은 EXIT 인 경우 이다. 자바 프로세스 종료시 EXIT 시그널이 오는 데, 그 때 loop를 사용하는 method_name를 다시 한번 사용하게 하였다.
종료는 9(SIGKILL) 시그널을 발생시켜서 종료하므로 문제 없이 stop을 할 수 있다.
리눅스에서 명령어를 연속 해서 사용 할 때가 있다.
보통 || 와 &&을 사용한다. 이를 단락 연산자(short-circuit operator)라고 한다.
첫번째 명령어를 실행하고 곧이어 두번째 명령어를 실행하는 역할이다.
예제는 다음과 같다.
[root@localhost ~]# true || echo 'ok' [root@localhost ~]# false || echo ok ok [root@localhost ~]#
[root@localhost ~]# true && echo 'ok' ok [root@localhost ~]# false && echo 'ok' [root@localhost ~]#
[root@localhost ~]# echo '1ok'; echo '2ok' 1ok 2ok [root@localhost ~]#
최근 추가한 코드를 테스트하는 개발서버에서 아래의 에러 메시지가 발생했다.
java.lang.OutOfMemoryError: Direct buffer memory at java.nio.Bits.reserveMemory(Bits.java:694) at java.nio.DirectByteBuffer.(DirectByteBuffer.java:123) at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311) at io.netty.buffer.UnpooledUnsafeDirectByteBuf.allocateDirect(UnpooledUnsafeDirectByteBuf.java:111) at io.netty.buffer.UnpooledUnsafeDirectByteBuf. (UnpooledUnsafeDirectByteBuf.java:68) at io.netty.buffer.UnsafeByteBufUtil.newUnsafeDirectByteBuf(UnsafeByteBufUtil.java:626) at io.netty.buffer.UnpooledByteBufAllocator.newDirectBuffer(UnpooledByteBufAllocator.java:65) at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:179) at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:170) at io.netty.buffer.AbstractByteBufAllocator.ioBuffer(AbstractByteBufAllocator.java:131) at io.netty.channel.DefaultMaxMessagesRecvByteBufAllocator$MaxMessageHandle.allocate(DefaultMaxMessagesRecvByteBufAllocator.java:73) at io.netty.channel.socket.nio.NioDatagramChannel.doReadMessages(NioDatagramChannel.java:243) at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:75) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:565) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:479) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) at java.lang.Thread.run(Thread.java:748)
추가한 부분은 udp 클라이언트 용도의 프로그램이었다.
소스를 분석해 봤지만 문제되는 부분을 알 수 없었다.
visulavm을 이용해 모니터링을 해봤더니, classes의 Total loaded 개수가 계속 증가하면서, Metaspace 영역이 계속 증가하는 현상을 확인했다.
dump를 받아서 mat 프로그램으로 분석했다. 잘 사용할 줄은 몰랐지만 대충 보다 보니 modelmapper가 보인다. 뭐지...
'modelmapper 성능 이슈'로 검색해 봤더니, 이런 글을 찾았다.
설마 하는 생각으로 modelmapper 부분을 제외했더니, 정상적으로 돌아왔다.
modelmapper는 예전부터 web 프로젝트에서 많이 사용했었기 때문에 이런 문제가 발생할 줄 몰랐다.
'modelmapper memory leak'으로 검색해서 더 알게 된 정보는 modelmapper는싱글톤으로 구성하여 사용하라는 것이다.
modelmapper를 많이 사용하지 않았기 때문에 전부 걷어내고 직접 지정하는 방식으로 변경했다.
이런 문제가 한 번 생기고 나니 modelmapper를 다시 사용하기 꺼려진다.
modelmapper memory leak으로 찾아 본 글
https://www.programmersought.com/article/1444628366/-Djava.security.egd=file:/dev/./urandom