문제

it's me again. And today, I'm facing kind of a weird problem. Either I didn't understand something correctly or I'm simply missing the forrest in front of the trees.

Following scenario:

  • I'm using JavaFX, bundled in JDK 1.7
  • I need both client runtimes: Desktop (jar) and Applet (jnlp inside the browser)
  • I have a maven project set up for the project
  • I have a parent pom and different sub modules
  • I need my client to communicate with a web service, that for I'v chosen CXF as framework (I need to be able to switch web services on runtime) for connecting to the web service
  • The 'connect to the web service stuff' is an own maven sub module called wsConnector

Here is some more environment information and my pom snippets:

mvn -version
Apache Maven 3.0.4 (r1232337; 2012-01-17 09:44:56+0100)
Maven home: C:\Program Files (x86)\Apache\maven-3.0.4\bin\..
Java version: 1.7.0_07, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.7.0_07\jre
Default locale: de_DE, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"

For being able to compile the wsConnector sub module, again which takes care about all the web service connection stuff, I need to integrate the tools.jar from the JDK as CXF needs that.

relevant properties from the parent pom.xml:

<properties>
    <maven.compiler.source>1.7</maven.compiler.source>
    ...
</properties>
        

sub module pom.xml:

<properties>
    <cxf.version>2.6.2</cxf.version>
</properties>

<dependencies>
    <dependency>
        ... // some other sub modules
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>${cxf.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>${cxf.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http-jetty</artifactId>
        <version>${cxf.version}</version>
    </dependency>
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>tools</artifactId>
        <version>${maven.compiler.source}]</version>
        <scope>system</scope>
        <systemPath>${java.home}/../lib/tools.jar</systemPath>
    </dependency>
</dependencies>

If I run mvn clean package, everything works fine and dandy. In the deploy directory of my client app (where the jar, generated HTML and jnlp file is also), I find the tools.jar, too.

If I have a look in the JNLP file, I find the entry:

<jar href="tools.jar" size="15226565" download="eager" />

Now my problem is: if I run the client with java -jar client.jar, everything works. But if I call the HTML / JNLP file, i get a ClassNotFoundException, pointing out that tools.jar is not on the classpath. Therefore, it doesn't care if I open the applet from a server or localhost.

Here is the stacktrace:

java.lang.IllegalStateException: Unable to create schema compiler
 at org.apache.cxf.common.jaxb.JAXBUtils.createSchemaCompilerWithDefaultAllocator(JAXBUtils.java:694)
 at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:303)
 at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:270)
 at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:263)
 at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:198)
 at com.multiguide.ws.WebServiceConnector.setWsdlUrl(WebServiceConnector.java:45)
 at com.multiguide.ws.WebServiceConnector.setWsdlUrl(WebServiceConnector.java:31)
 at com.multiguide.view.administration.WebServiceInformationPanel.connect(WebServiceInformationPanel.java:130)
 at com.multiguide.view.administration.WebServiceInformationPanel.refresh(WebServiceInformationPanel.java:70)
 at com.multiguide.view.administration.WebServiceInformationPanel.<init>(WebServiceInformationPanel.java:45)
 at com.multiguide.view.administration.WebServiceInformationPanel$$FastClassByGuice$$da5f387e.newInstance(<generated>)
 at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40)
 at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:60)
 at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85)
 at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
 at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
 at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
 at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:84)
 at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
 at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
 at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
 at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
 at com.google.inject.Scopes$1$1.get(Scopes.java:65)
 at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
 at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
 at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
 at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:84)
 at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
 at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:54)
 at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
 at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
 at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:84)
 at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
 at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
 at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
 at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
 at com.google.inject.Scopes$1$1.get(Scopes.java:65)
 at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
 at com.google.inject.internal.InjectorImpl$4$1.call(InjectorImpl.java:978)
 at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
 at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:974)

... 9 more
Caused by: javax.xml.bind.JAXBException - with linked exception:

java.lang.ClassNotFoundException: com/sun/tools/internal/xjc/api/XJC
 at org.apache.cxf.common.jaxb.JAXBUtils.createSchemaCompiler(JAXBUtils.java:679)
 at org.apache.cxf.common.jaxb.JAXBUtils.createSchemaCompilerWithDefaultAllocator(JAXBUtils.java:686)

... 49 more
Caused by:

java.lang.ClassNotFoundException: com/sun/tools/internal/xjc/api/XJC
 at java.lang.Class.forName0(Native Method)
 at java.lang.Class.forName(Unknown Source)
 at org.apache.cxf.common.jaxb.JAXBUtils.createSchemaCompiler(JAXBUtils.java:672)

... 50 more

Is it a class loading issue as I'm using guice? Without this exception, the app is working like a charme. I can do all the web service stuff I need to do: connecting, switching URL, ... So I wouldn't expect that to be the reason.

Note besides: I think it doesn't matter here right now, but as I'm using guice, of course my JNLP file has the

<security>
  </all-permissions>
</security>

flag.

Has anyone of you experiences with that? Maybe I really just miss a thing, but any help (as always ;) ) is highly appreciated :)

도움이 되었습니까?

해결책

finally I got the tools.jar in the classpath. I figured out it was missing in the manifest of my jar-file I'm delivering and which contains my client application.

As this is a JavaFX application, I needed to add the tools.jar dependency within the classpath tag of the configuration of the manifest file of the client sub module:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifestEntries>
                        ...
                        <Class-Path>jfxrt.jar tools.jar</Class-Path>
                    </manifestEntries>
                    <manifest>
                        <addClasspath>true</addClasspath>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

After having tools.jar in the classpath, CXF tries to call the java compiler, see the error message:

org.apache.cxf.common.jaxb.JAXBUtils logGeneratedClassNames
INFO: Created classes: <list of my generated JAVA files from the wsdl file here>
[ERROR] IOException during exec() of compiler "javac". Check your path environment variable.
Okt 23, 2012 3:46:20 PM org.apache.cxf.endpoint.dynamic.DynamicClientFactory createClient
SEVERE: Could not compile java files for <url to wsdl file here>.

So this means for me that I would need to require having a JDK running and set up on a client machine. If I would serve the javac too (just a thought play don't blame me :) ), this would mean that I'd need to execute something on the client machine, which is a no-go for me.

That for, I will find an alternative solution for what I initially wanted (solution will be outsourcing the generate-ws-accessing-classes).

Though, for the initial question of how to integrate tools.jar in the classpath, what I've written above solved the problem for me.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top