2016-04-25 4 views
2

Ich erstelle das Installationsprogramm für Windows- und Linux-Systeme. Nach dem Begrüßungsbildschirm habe ich eine CustomForm-Komponente, wo ich Benutzerdetails aufnehmen und sie dann an einen Server senden, der javax.ws.rs.client.ClientBuilder verwendet. Wenn die Klasse "my" in Windows versucht, den Client über ClientBuilder zu erstellen, gibt das Installationsprogramm java.lang.LinkageError: ClassCastException aus. Das gesamte Protokoll unten angegeben:Install4j: Windows-Installer zeigt java.lang.LinkageError: ClassCastException

java.lang.LinkageError: ClassCastException: attempting to cast 
jar:file:/C:/Users/lutful.kabir/AppData/Local/Temp/e4j363A.tmp_dir1460795758/user/javaee-api-7.0.jar!/javax/ws/rs/client/ClientBuilder.class to 
jar:file:/C:/Users/lutful.kabir/AppData/Local/Temp/e4j363A.tmp_dir1460795758/user/javaee-api-7.0.jar!/javax/ws/rs/client/ClientBuilder.class 
at javax.ws.rs.client.ClientBuilder.newBuilder(ClientBuilder.java:97) 
at javax.ws.rs.client.ClientBuilder.newClient(ClientBuilder.java:114) 
at install4j.AuthorizationHandler.verifyAuthorization(AuthorizationHandler.java:21) 
at install4j.backendsetup.VerifyBackend.install(VerifyBackend.java:27) 
at com.install4j.runtime.installer.InstallerContextImpl$2.fetchValue(InstallerContextImpl.java:167) 
at com.install4j.runtime.installer.InstallerContextImpl$2.fetchValue(InstallerContextImpl.java:164) 
at com.install4j.runtime.installer.helper.comm.actions.FetchObjectAction.execute(FetchObjectAction.java:14) 
at com.install4j.runtime.installer.helper.comm.HelperCommunication.executeActionDirect(HelperCommunication.java:272) 
at com.install4j.runtime.installer.helper.comm.HelperCommunication.executeActionInt(HelperCommunication.java:247) 
at com.install4j.runtime.installer.helper.comm.HelperCommunication.executeActionChecked(HelperCommunication.java:185) 
at com.install4j.runtime.installer.helper.comm.HelperCommunication.fetchObjectChecked(HelperCommunication.java:168) 
at com.install4j.runtime.installer.InstallerContextImpl.performActionIntStatic(InstallerContextImpl.java:164) 
at com.install4j.runtime.installer.InstallerContextImpl.performActionInt(InstallerContextImpl.java:152) 
at com.install4j.runtime.installer.ContextImpl.performAction(ContextImpl.java:1099) 
at com.install4j.runtime.installer.controller.Controller.executeAction(Controller.java:367) 
at com.install4j.runtime.installer.controller.Controller.executeActions(Controller.java:333) 
at com.install4j.runtime.installer.controller.Controller.handleCommand(Controller.java:194) 
at com.install4j.runtime.installer.controller.Controller.start(Controller.java:94) 
at com.install4j.runtime.installer.Installer.runInProcess(Installer.java:59) 
at com.install4j.runtime.installer.Installer.main(Installer.java:46) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:606) 
at com.exe4j.runtime.LauncherEngine.launch(LauncherEngine.java:62) 
at com.exe4j.runtime.WinLauncher.main(WinLauncher.java:101) 
at com.install4j.runtime.launcher.WinLauncher.main(WinLauncher.java:26) 

Der Code für AuthorizationHandler folgt:

package install4j; 

import java.net.ConnectException; 

import javax.ws.rs.client.Client; 
import javax.ws.rs.client.ClientBuilder; 
import javax.ws.rs.client.Invocation; 
import javax.ws.rs.client.Invocation.Builder; 
import javax.ws.rs.client.WebTarget; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 

import com.install4j.api.Util; 
import com.install4j.api.context.InstallerContext; 

import installerconfigparams.utils.InstallerParameter; 

public class AuthorizationHandler { 

    public static boolean verifyAuthorization(String authToken, InstallerContext context) throws ConnectException { 
     Client client = ClientBuilder.newClient(); 
     WebTarget target = client.target(InstallerParameter.CENTRAL_SERVER_URL.getStringValue()) 
       .path(InstallerParameter.PATH_BACKEND_VERIFICATION.getStringValue()); 
     Builder builder = target.request(MediaType.APPLICATION_JSON); 
     builder.header(InstallerParameter.AUTHORIZATION_HEADER.getStringValue(), authToken); 
     Invocation invocation = builder.buildGet(); 
     Response response; 
     response = invocation.invoke(); 
     response.getStringHeaders(); 
     int status = response.getStatus(); 
     if (InstallerParameter.HTTP_200.getIntValue() != status) { 
      String args = response.getHeaderString("error"); 
      Util.showErrorMessage(context.getMessage("installer.backend.login.invalid") + args); 
      return false; 
     } 
     Util.showMessage(context.getMessage("installer.backend.login.successful")); 
     return true; 
    } 

Nun, so weit ich weiß, und basiert auf meiner Internet-Recherche, kann dies passieren, wenn es vielleicht doppelte Ressourcen (aus dem Protokoll können Sie auch sehen, dass die ClientBuilder Klassen, die es verwendet, auch von identischen Pfaden sind). Ich habe sichergestellt, dass keine doppelten Jars hinzugefügt wurden, so dass der Installer sie verwechseln kann. Ich kenne mich mit ClassLoadern und dessen Funktionsweise für Install4j nicht aus. Ich habe auch versucht, die Run Script Aktion zu verwenden, indem ich die Codes direkt dort schrieb, aber endete, die gleiche Ausnahme zu haben.

Ich habe die gleichen Klassen und Methoden verwendet, seit ich den Installer gebaut habe. Und hatte bis heute kein Problem. Ich habe sogar nach meinem alten Commit Ausschau gehalten, bevor ich mit diesem Problem konfrontiert wurde. Aber das Ergebnis ist das Gleiche. Und dieses Problem tritt nur für das Installationsprogramm in Windows auf.

+1

Könnte es ein Problem mit dem Kontextklassenladeprogramm sein? Versuchen Sie 'Thread.currentThread() hinzuzufügen. SetContextClassLoader (getClass(). GetClassLoader());' am Anfang der Methode. –

+0

wow !! Es funktioniert, zumindest in meiner lokalen Maschine. Können Sie mir bitte das Problem in der Antwort im Detail erklären? – ShaDooW

Antwort

2

JAX-WS verwendet den Kontextklassenlader für einige Operationen. Aufruf

Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); 

setzt den Kontext Class Loader auf der gleichen Klasse Loader, der das Skript lädt, die seit install4j 6.1 aus dem System Class Loader unterscheidet.

Beginnend mit install4j 6.1.2 wird der Context Class Loader automatisch angepasst, so dass die obige Problemumgehung nicht mehr notwendig ist.