주어진 URL에서 새 버전 (.jar 파일)을 다운로드 한 다음 런타임에 업데이트 할 수있는 Java 응용 프로그램 (서버 응용 프로그램)을 구현하고 싶습니다.
이를 수행하는 가장 좋은 방법은 무엇이며 가능합니까?
응용 프로그램이 새 .jar 파일을 다운로드하여 시작할 수 있다고 생각합니다. 그러나 어떻게 핸드 오버를해야합니까? 예를 들어 새 응용 프로그램이 언제 시작되고 종료되는지 알 수 있습니다. 아니면 더 좋은 방법이 있습니까?
답변
솔루션의 기본 구조는 다음과 같습니다.
-
앱의 최신 버전을 반복적으로로드하고 (필요한 경우) 실행하는 메인 루프가 있습니다.
-
응용 프로그램은 그 일을하지만 주기적으로 다운로드 URL을 확인합니다. 새 버전을 감지하면 런처로 돌아갑니다.
이를 구현할 수있는 방법에는 여러 가지가 있습니다. 예를 들면 :
-
런처는 대체되는 JAR 파일에서 애플리케이션을 실행하기 위해 새 JVM을 시작하는 랩퍼 스크립트 또는 바이너리 애플리케이션 일 수 있습니다.
-
런처는 새 JAR에 대한 클래스 로더를 작성하고 진입 점 클래스를로드하고 여기에 일부 메소드를 호출하는 Java 애플리케이션 일 수 있습니다. 이런 식으로하면 클래스 로더 저장소 누수를 감시해야하지만 어렵지 않습니다. (재실행 후 JAR에서로드 된 클래스가있는 객체에 도달 할 수 없는지 확인하기 만하면됩니다.)
외부 래퍼 접근 방식의 장점은 다음과 같습니다.
- JAR 하나만 필요합니다.
- 전체 Java 앱을 대체 할 수 있습니다.
- 앱 등에서 생성 된 보조 스레드는 특별한 종료 로직없이 사라집니다.
- 응용 프로그램 충돌 등으로부터 복구를 처리 할 수도 있습니다.
두 번째 접근 방식에는 두 개의 JAR이 필요하지만 다음과 같은 이점이 있습니다.
- 솔루션은 순수 Java이며 이식 가능합니다.
- 전환이 더 빨라지고
- 다시 시작하는 동안 상태를 더 쉽게 유지할 수 있습니다 (모듈로 누출 문제).
“최상의”방법은 특정 요구 사항에 따라 다릅니다.
또한 다음 사항에 유의해야합니다.
-
자동 업데이트에는 보안 위험이 있습니다. 일반적으로 업데이트를 제공하는 서버가 손상되었거나 업데이트를 제공하는 메커니즘이 공격에 취약한 경우 자동 업데이트로 인해 클라이언트가 손상 될 수 있습니다.
-
고객에게 피해를주는 업데이트를 고객에게 푸시하면 법적 위험이있을 수 있으며 비즈니스 평판에 위험이 발생할 수 있습니다.
바퀴를 재발 명하지 않는 방법을 찾을 수 있다면 좋을 것입니다. 제안 사항은 다른 답변을 참조하십시오.
답변
저는 현재 JAVA Linux Daemon을 개발 중이며 자동 업데이트 메커니즘을 구현해야했습니다. 내 응용 프로그램을 하나의 jar 파일로 제한하고 간단한 해결책을 찾았습니다.
업데이트 자체에 업데이트 프로그램 응용 프로그램을 압축합니다.
응용 프로그램 : 응용 프로그램이 최신 버전을 감지하면 다음을 수행합니다.
- 업데이트 다운로드 (Zipfile)
- 응용 프로그램 및 ApplicationUpdater 추출 (모두 zip 파일에 있음)
- 업데이터 실행
ApplicationUpdater : 업데이트 프로그램이 실행되면 다음을 수행합니다.
- 응용 프로그램을 중지하십시오 (제 경우에는 init.d를 통한 데몬)
- 다운로드 한 jar 파일을 복사하여 현재 애플리케이션을 덮어 씁니다.
- 응용 프로그램 시작
- 대청소.
누군가에게 도움이되기를 바랍니다.
답변
이것은 알려진 문제이며 바퀴를 재발 명하지 않는 것이 좋습니다. 자신의 해킹을 작성하지 말고 다른 사람들이 이미 한 것을 사용하십시오.
고려해야 할 두 가지 상황 :
-
앱은 자체 업데이트가 가능하고 업데이트 중에도 계속 실행되어야합니다 (서버 앱, 임베디드 앱). OSGi로 이동 : 번들 또는 Equinox p2 .
-
앱은 데스크톱 앱이며 설치 프로그램이 있습니다. 업데이트 옵션이있는 설치 프로그램이 많이 있습니다. 설치자 목록을 확인하십시오 .
답변
최근 Java 9의 모듈 시스템과 완벽하게 호환되는 update4j 를 만들었습니다 .
다시 시작하지 않고도 새 버전을 원활하게 시작합니다.
답변
jEdit의 유사한 메커니즘에서 영감을 받아 런타임에 플러그인을로드하고 즉시 사용할 수있는 Java 애플리케이션을 작성했습니다. jEdit는 오픈 소스이므로 작동 방식을 볼 수있는 옵션이 있습니다.
이 솔루션은 사용자 정의 ClassLoader를 사용하여 jar에서 파일을로드합니다. 일단로드되면 새 jar에서 해당 main
메서드 로 작동 할 메서드를 호출 할 수 있습니다 . 그런 다음 까다로운 부분은 가비지 수집이 가능하도록 이전 코드에 대한 모든 참조를 제거하는 것입니다. 나는 그 부분에 대한 전문가가 아니고 그것을 작동하도록 만들었지 만 쉽지 않았습니다.
답변
- 첫 번째 방법 : 바람둥이를 사용하고 시설을 배포합니다.
- 두 번째 방법 : 응용 프로그램을 두 부분 (기능 및 업데이트)으로 분할하고 업데이트 부분이 기능 부분을 대체하도록합니다.
- 세 번째 방법 : 서버 응용 프로그램에서 새 버전을 다운로드 한 다음 이전 버전이 바인딩 된 포트를 릴리스 한 다음 이전 버전이 새 버전을 실행 (프로세스 시작) 한 다음 이전 버전이 응용 프로그램 포트에 대한 요청을 새 버전으로 전송하여 이전 버전, 이전 버전을 삭제합니다. 종료되고 새 버전은 이전 버전을 삭제합니다. 이렇게 :
답변
이것이 반드시 최고 는 아닙니다. 방법은 아니지만 귀하에게 적합 할 수 있습니다.
부트 스트랩 애플리케이션을 작성할 수 있습니다 (WoW를 플레이 한 경우 월드 오브 워크래프트 런처라고도 함). 해당 부트 스트랩은 업데이트 확인을 담당합니다.
- 사용 가능한 업데이트가 있으면 사용자에게 제공하고 다운로드, 설치 등을 처리합니다.
- 응용 프로그램이 최신 상태이면 사용자가 응용 프로그램을 시작할 수 있습니다.
- 선택적으로 최신 상태가 아니더라도 사용자가 애플리케이션을 실행하도록 허용 할 수 있습니다.
이렇게하면 애플리케이션을 강제 종료하는 것에 대해 걱정할 필요가 없습니다.
애플리케이션이 웹 기반이고 최신 클라이언트가 있어야하는 경우 애플리케이션이 실행되는 동안 버전 확인을 수행 할 수도 있습니다. 서버와의 정상적인 통신 (일부 또는 모든 호출) 또는 둘 다를 수행하면서 간격을두고 수행 할 수 있습니다.
최근에 작업 한 제품의 경우 시작시 (부트 스트 래퍼 앱없이 기본 창이 표시되기 전) 및 서버 호출 중에 버전 확인을 수행했습니다. 클라이언트가 오래되었을 때 우리는 사용자가 수동으로 종료하도록 의존했지만 서버에 대한 어떠한 조치도 금지했습니다.
메인 창을 열기 전에 Java가 UI 코드를 호출 할 수 있는지 알 수 없습니다. 우리는 C # / WPF를 사용하고있었습니다.