Details
-
Type:
New Feature
-
Status:
Reopened
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: None
-
Fix Version/s: 1.0-beta-4
-
Component/s: jnlps
-
Labels:None
-
Patch Submitted:Yes
-
Number of attachments :8
Description
nativelib are resiyrces that are tagged in the following way in a jnlp file:
<resources os="Windows">
<nativelib href="thedll.jar"/>
</resources>
To support nativelib at the same level of simplicity that the usual dependencies are supported requires to:
- automatically identify them from
- automatically wrap .dll .so files in jar files
Q: what about jar files that are architecture dependent?
In maven 1 it was possible to attach some properties to the dependencies. But we cannot use that anymore.
We could
1- mark the dependencies in the pom using the correct <type> in the pom. E.g. <type>dll</type>
2- make the plugin automatically wrap the native dependency inside a jar.
3- automatically fill up the <nativelib> elements using some sort of filter mecanism
<resources os="Windows">
$allDependencies.filter("dll")
</resources>
??
$dependencies would implicitly map to $allDependencies.filter("jar") for backward compatibility.
Better: the filter() argument might be a JDK 1.4 regex matching a dependency notation. That way we solve the architecture issue (we can match names, types, etc..)
That's just one idea. We can perhaps do better? Let me know how you see it.
-
- jnlpMaven.diff
- 06/Jun/09 2:46 PM
- 2 kB
- Ruben Garat
-
- jnlptemplate.vm
- 06/Aug/09 8:28 AM
- 2 kB
- Ruben Garat
-
- MWEBSTART-8.diff
- 28/Dec/06 6:20 PM
- 4 kB
- Jerome Lacoste
-
- MWEBSTART-8a.diff
- 27/Sep/07 10:38 AM
- 12 kB
- Trey Sleeper
-
- MWEBSTART-8b.patch
- 09/May/08 10:02 AM
- 8 kB
- David Bernard
-
- MWEBSTART-8c.patch
- 13/May/08 3:03 AM
- 16 kB
- David Bernard
-
- MWEBSTART-8d.patch
- 14/Nov/12 10:40 AM
- 41 kB
- Ajay Deshwal
-
- native-9.patch
- 29/Nov/12 9:34 AM
- 40 kB
- Will Tatam
Activity
Craig,
if I understand you, if you are able to add something like
<nativelibs>
<nativelib>yourdep1</nativelib>
<nativelib>yourdep2</nativelib>
</nativelibs>
in your POM then make sure something like
#foreach($artifact in $config.packagedJnlpNativeArtifacts)
<resources #if($jar.os) os="$
" #end>
<nativelib href="$
"/>
</resources>
#end
works in the velocity template, making sure that native artifacts are removed from the list of 'normal' artifacts (packagedJnlpArtifacts).
That would be sufficient right ?
Completely untested patch.... Store it here in case my disk crah (as in YNK 'you-never-know').
After thinking about it, I don't want to touch this until I get a more complete use case. Minimal support can be added quickly (along the lines of the incomplete patch I provided), but we probably want to support at least <resources> attributes such as os or arch.
If someone comes with a real life test case, then I will look into it.
A good test case might be to try to support jdic (https://jdic.dev.java.net/documentation/deployment.html).
Any SWT-based application should make a decent use case.
An application which shows an empty SWT shell on the screen requires a dependency like this:
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>swt</artifactId>
<version>3.2.0</version>
</dependency>
This contains the java code. In our case, it also contains the windows dll. We stuffed the windows dll in the main swt java jar in order to reduce the manual work required after running mvn webstart:jnlp. Now all we have to do is duplicate the above dependency line in the launch.jnlp file, and mark the duplicate as nativelib.
This is a workaround, and might not be your best use case.
Instead, I would expect most users to keep the above dependency java-only, and add a dependency like this:
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>swt-win32</artifactId>
<version>3232</version>
<type>dll</type>
</dependency>
This works, well enough to pull the dll down to the local maven repo. I wish Eclipse would put the dll on the classpath automatically, but it isn't that smart.
But, if the webstart plugin could:
- recognize the native libs based on type
- jar them
- sign them along with everybody else
- include them as nativelib in the jnlp
that would be a great start.
Additionally, one would want to map them to environments in the pom. (Windows vs Mac vs Linux...)
Reopen, hopefully someone will send me a complete test case and a patch ![]()
Jerome,
I've got a patch developed for supporting native libraries as we use them. All native dependencies are already packaged into jars by platform. The direction I took was to add them as normal dependencies so they'd be signed/packed as normal, but added filtering in the <jnlp> config section of the pom. Ex:
...
<dependencies>
...
<dependency>
<groupId>blah.jni.win32</groupId>
<artifactId>hello-win32</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>blah.jni.linux</groupId>
<artifactId>hello-linux</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
...
</dependencies>
...
<jnlp>
<outputFile>pocJws.jnlp</outputFile>
<mainClass>blah.Main</mainClass>
<nativeLibs>
<nativeLib>
<groupId>blah.jni.win32</groupId>
<artifactId>hello-win32</artifactId>
<os>Windows</os>
</nativeLib>
<nativeLib>
<groupId>blah.jni.linux</groupId>
<artifactId>hello-linux</artifactId>
<os>Linux</os>
</nativeLib>
</nativeLibs>
</jnlp>
...
The <nativeLib> element will also accept an <arch> element. All <nativeLib> elements with matching os/arch combinations will be grouped into the same <resources> tag in the jnlp. The template placeholder is just a $nativeLibs entry
...
<resources>
<j2se version="1.5+"/>
$dependencies
</resources>
$nativeLibs
<application-desc main-class="$mainClass"/>
...
I'm new to open-source contribution, so a few questions:
1. Does this solution look passable to you?
2. How do I get the patch to you?
3. What sort of test case coverage are you looking for?
I'd be very interested to see the patch mentioned above. I have a need for the exact same functionality, and this could save me a lot of time grokking/writing/debugging, etc. Can you attach it to this issue, and I'll see about maybe creating a test case?
I've attached the diff. My main concern with my patch is that it only addresses the "legacy" classes such as Generator, JarResource etc. Since I'm still using the jnlp-inline goal, I didn't touch the new JarResourcesGenerator, VersionXmlGenerator and others.
These classes follow a similar generator pattern, so I could add the new logic to them also if that looks to be the new direction of development of this plugin. Jerome, can you let us know?
Trey sorry for the delay.
I am not using the other generators so far. All those have been contributions that seemed valid from users. I in fact don't use the webstart plugin a lot these days...
The current patch doesn't apply to the trunk. Should be simple to fix. As for your question, I would like this to fit with the rest of the code, although it's too late today for me to decide whether this is right or wrong ![]()
Is there someone else than Trey using this patch ? John, did you try it ? Trey, have you tried using the other mojos (in particular the Download servlet one) ?
We'd like to try the patch here but it would be easier if it were in a release. (I got the patch to apply and compile but don't have the maven skills yet to actually make it so this local version is used as the plugin.) The functionality as described sounds fine. It would be nice to avoid explicitly listing every DLL under the jnlp config. At least in our case we are only targeting Windows, so we don't need the functionality of saying "this lib is for this OS", though obviously that's a needed case.
Adrian, I will look into that after releasing alpha-2. Please test and vote for alpha-2 on the user list.
<os>Linux</os>
the os should be lowercase, to be in sync with how profiles, assembly's work etc:
<os>linux</os>
I create a patch from the 8b (adapter to work on Trunk rev 6924 (1.0-beta-1)).
I also add into the patch :
- a special management of the 'os' attribut. the os attribute should match the System.getProperty("os.name"), then os="Linux" work but os="linux" don't. To avoid stupid problem, or be able to use same label as assemblies,... the patch correct case for "Windows", "Linux", "SunOs", "Mac OS X", "Mac OS", "Solaris" (other value are left "as is")
- support for 'locale' attribute
- support for classifier
ex
in pom.xml
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl_native</artifactId>
<version>1.1.3</version>
<classifier>linux</classifier>
</dependency>
<jnlp>
...
<nativeLibs>
<nativeLib>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl_native</artifactId>
<classifier>linux</classifier>
<os>linux</os>
</nativeLib>
</nativeLibs>
in template.vm
<resources>
<j2se version="1.6+" initial-heap-size="64m" max-heap-size="512m" />
$dependencies
</resources>
$nativeLibs
David, the patch lacks at least one class: NativeLibResourcesGenerator
Oups, I forgot svn need explicit add, sorry, I'll post the past Tuesday (Monday is day off and the patch is at office).
Sorry
David,
Some comments. Great if you can address them
- can you fix the code style ? In particular related. do a mvn site and look at the checkstyle report for your new code.
- move
StringBuffer buffer = new StringBuffer();
just before
if (!libsByOsArch.isEmpty()) {
we're not coding in C ![]()
- + public static String getDependenciesText(AbstractJnlpMojo config, NativeLibResourcesGenerator nativeLibGen)
The new dummy javadoc doesn't add anything -> remove it.
Don't change the visibility of the method without reason neither. The class uses a default and not public modifier as it is only exposed for unit testing purposes.
I don't like much how we expose the native lib generator parameter here. I'll look into this later on.
we ought to have new unit tests for the following case:
- ignoring native libs when generating getDependenciesText()
- test getNativeLibDependenciesText
is that something you can contribute ?
- + * Copyright 2005 Nick C . Who 's Nick ?
- return new ArrayList(0); -> Collections.EMPTY_LIST
- the best thing for me would be to get a simple integration test. Look at src/it/... and create a test project there.
Now once you fix this, I will commit it. The only thing that will missing will be support of native libs in the jnlp download servlet mojo. I am trying to get them more similar feature/code wise.
Hi Jerome,
I could work on your request (next week-end at home) :
- can you fix the code style ? In particular related. do a mvn site and look at the checkstyle report for your new code.
OK
- move
StringBuffer buffer = new StringBuffer();
just before
if (!libsByOsArch.isEmpty()) {
we're not coding in C ![]()
I didn't re-read the original patch (only adapt it to work)
- + public static String getDependenciesText(AbstractJnlpMojo config, NativeLibResourcesGenerator nativeLibGen)
The new dummy javadoc doesn't add anything -> remove it.
??
Don't change the visibility of the method without reason neither. The class uses a default and not public modifier as it is only exposed for unit testing purposes.
I change it with a reason, but I didn't remember why (I've some trouble with eclipse, so I can't check now). I'll fix or fine the reason
I don't like much how we expose the native lib generator parameter here. I'll look into this later on.
we ought to have new unit tests for the following case:
- ignoring native libs when generating getDependenciesText()
- test getNativeLibDependenciesText
agree, I never used shitty, I took a quick overlook, but I didn't find a existing test case that check the content of the jnlp. I search for it as an example to create the a test for nativelibs.
Could you point me where to find the right sample test ?
is that something you can contribute ?
I'll try
- + * Copyright 2005 Nick C . Who 's Nick ?
I didn''t, it is part of the origanal patch I didn't change the license, only add my name in the javadoc.
- return new ArrayList(0); -> Collections.EMPTY_LIST
+1
- the best thing for me would be to get a simple integration test. Look at src/it/... and create a test project there.
see above.
Now once you fix this, I will commit it. The only thing that will missing will be support of native libs in the jnlp download servlet mojo. I am trying to get them more similar feature/code wise.
thanks for your feedback.
I probably provide other contributions :
- I found an other issue (resource are copied under libDir, I'll fix it)
- I would like to generate html for jnlp/applet with velocity.
/davidB
> I could work on your request (next week-end at home) :
David, all in all sounds great.
>I didn't re-read the original patch (only adapt it to work)
OK
I didn't mean to imply that you were the one to have coded the file, just as there are a couple of small things to clean, that you could do it !
- + public static String getDependenciesText(AbstractJnlpMojo config, NativeLibResourcesGenerator nativeLibGen)
>> The new dummy javadoc doesn't add anything -> remove it.
> ??
the empty javadoc just before the method getDependenciesText
>> Don't change the visibility of the method without reason neither. The class uses a default and not public modifier as it is only exposed
>> for unit testing purposes.
> I change it with a reason, but I didn't remember why (I've some trouble with eclipse, so I can't check now). I'll fix or fine the reason
OK ![]()
>> I don't like much how we expose the native lib generator parameter here. I'll look into this later on.
>>
>> we ought to have new unit tests for the following case:
>> * ignoring native libs when generating getDependenciesText()
>> * test getNativeLibDependenciesText
> agree, I never used shitty, I took a quick overlook, but I didn't find a existing test case that check the content of the jnlp. I search for it
> as an example to create the a test for nativelibs.
> Could you point me where to find the right sample test ?
For the unit tests, use plain JUnit. For the integration tests (i.e. full POM example), use shitty.
For your particular integration tests, just pick one simple itxxx project that uses jnlp-inline attached to a particular phase, and change it so that it uses native libraries). Not sure if there are some trusted simple native project available somewhere for us to test.
Otherwise we could create one ourselves. E.g. one helloworld-native project with a single native function that does something like
String hello(String name) -> hello("Jerome") could return "Hello Jerome!".
we could use http://mojo.codehaus.org/maven-native/native-maven-plugin/ and generate it on the fly, but I guess we need to compile it and release it for several platforms for the test to be meaningful.
Not sure how one deals with release of native projects that need to be compiled for several platforms...
>> is that something you can contribute ?
> I'll try
>> * + * Copyright 2005 Nick C . Who 's Nick ?
> I didn''t, it is part of the origanal patch I didn't change the license, only add my name in the javadoc.
OK. Strange as his name is nowhere on the list of people in that issue. Maybe a copy paste issue. I think I will take it out.
> I probably provide other contributions :
>
> * I found an other issue (resource are copied under libDir, I'll fix it)
> * I would like to generate html for jnlp/applet with velocity.
OK. Just provide them as separate patches and open new Jira issues.
Cheers,
Jerome
We'd like to use this patch but looks like it doesn't apply for JnlpDownloadServletMojo which we are using.
From a quick glance I'm quite surprise that JnlpDownloadServletMojo doesn't reuse JnlpConfig element so it doesn't benefit from the patch.
Jerome, can you shed some light into why this is the case?
Ronn,
different contributors wrote the standard jnlp mojos and the JnlpDownloadServlet one. The later was written after the other and came with more feature. I haven't taken the time to merge them both. I haven't used webstart in any of my personal or professional projects in 2 years, so I have less incentive to fix this as if I was using it. Help appreciated ![]()
The reason for the configuration discrepancy between the various mojos is why webstart 1.0 is not out yet, nor in beta. I want to fix this issue, MWEBSTART-58 and allow the jnlp mojos to have jarArtifacts as the jnlp download servlet does (these last 2 will impact the configuration format). Once those are fixed, 1.0-beta-1 can be released and we can go towards 1.0.
Another solution is to release 1.0 now and then go towards 2.0 to notify of the broken format, or to support both old and new format. Comments appreciated ![]()
Jerome
Thanks for the info Jerome,
We primarily going to be using JnlpDownloadServlet so we have a need to make it work for us. I think in order to rectify internal structural differences between the mojos properly we would have to make changes to the configuration format (possibly remodel) - which could impact existing users. So in that respect, doing the minimal to fix 1.0-beta-1 to get it release is probably better in my view.
I'm always grateful for any workable patches but in terms of approach for this particular bug, I'm wondering why we need such a verbose and explicit configuration?
i.e.,
<nativeLibs>
<nativeLib>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl_native</artifactId>
<classifier>linux</classifier>
<os>linux</os>
</nativeLib>
</nativeLibs>
The hack I've done for us is to generate different XML snippet for different type of classifier found in the dependencies i.e., in JarResourcesGenerator.getDependenciesText(). This is simplistic and only works for one native platform but we could extend the approach so that the mojo scan through and groups dependencies of each classifier an generate separate resources group declarations.
That way any native libs found that are classified as the available os (i.e., linux/win32/solaris) will be automatically picked up without any additional configuration. If anything needs to be exclude then it should be done with the standard dependencies exclusion. Any additional inclusion are simply defined as another dependency. Mind you JnlpDownloadServletMojos doesn't yet support exclusion!
The only issue that I can still see is that this doesn't solve a scenario where you have specific java classes for a particular os. May be we could encode this additional information into the classifiers i.e., win32(for win32 java classes), win32-native (for win32 native libraries), linux-native, solaris-native.
Ronn, I am all for simplified POM configuration. David what do you think of the approach above ? I don't see obvious limitation, but people working with the JNLP spec on a day to day basis might see something.
I'm ok with simplification. But it should take care of :
- os could be set in the classifier or in the artifactId, or groupId : there is no rule (I saw 2 of 3 cases)
- os could be set as a subdirectory in a zip artifact, these case exists, could be handled with manual operation
- support several native platform
I don't understand the ronn's hack. (sorry). Could you provide example (configuration + result) ?
about JnlpDownloadServlet, harmonisation is good. I don't use it (currently).
I suppose that any patches are welcomes (I'm not a committer).
Hi David,
> * os could be set in the classifier or in the artifactId, or groupId : there is no rule (I saw 2 of 3 cases)
Perhaps there should be, this is what maven is good at - defining convention. I think enforcing user to classify their artifact as native lib is a good thing (even if it is already specified in artifact id or group id).
> * os could be set as a subdirectory in a zip artifact, these case exists, could be handled with manual operation
Same as above. As long as the jar is uploaded into repository with the expected classification it doesn't matter about the structure inside the jar.
> * support several native platform
We could add a configuration to add/override a list of os to scan for - the default would be linux, win32, solaris
Here's what I've done to support our jdic-native.jar (we only need to support win32 libraries) so in the repository i've got
~/.m2/repository/org/jdesktop/jdic-native/20061102/jdic-native-20061102-win32.jar
And
~/.m2/repository/org/jdesktop/jdic/20061102/jdic-20061102.pom depends on jdic-native (with win32 classification)
No other configuration needed.
Here's a diff in our svn (note it's reverse svn diff -c -29026)
Index: src/main/java/org/codehaus/mojo/webstart/generator/JarResourcesGenerator.java
===================================================================
--- src/main/java/org/codehaus/mojo/webstart/generator/JarResourcesGenerator.java (revision 29026)
+++ src/main/java/org/codehaus/mojo/webstart/generator/JarResourcesGenerator.java (revision 29025)
@@ -81,15 +81,9 @@
{
continue;
}
-
- // RC: hack to allow native lib to be declared properly.
- if ("win32".equalsIgnoreCase(jarResource.getClassifier())) {
- buffer.append( "<nativelib href=\"" ).append( jarResource.getHrefValue() ).append( "\"" );
- }
- else {
- buffer.append( "<jar href=\"" ).append( jarResource.getHrefValue() ).append( "\"" );
- }
-
+
+ buffer.append( "<jar href=\"" ).append( jarResource.getHrefValue() ).append( "\"" );
+
if ( jarResource.isOutputJarVersion() )
{
buffer.append(" version=\"").append(jarResource.getVersion()).append("\"");
The output is something like this, and obviously it only works for one platform but that suits us fine.
<resources>
<jar href="jdic.jar" version="20061102"/>
<nativelib href="jdic-native-win32.jar" version="20061102"/>
</resources>
Another more powerful option, is to make velocity do more work, and the plugin less work. For example, something like this:
<resources>
<j2se version="$j2seVersion"/>
#foreach( $dependency in $dependencies )
#if ( $dependency.classifier == null )
<jar href="lib/$
#end
#end
</resources>
<resources os="Windows" arch="x86">
#foreach( $dependency in $dependencies )
#if ( $dependency.classifier == 'win-x86' )
<jar href="lib/${dependency.artifactId}
-#
{depedency.version}.jar" />
#end
#end
</resources>
This way the template author has all the power instead of needing the MOJO to do all the work.
I think that's a great idea Andrew. That way we have flexibility of hacking the logic if needed.
hi, was this ever implemented?
I made a little hack to the 1.0-alpha-2 codebase to expose the dependencies in the velocity context and used a template similar to the one posted by Andrew and it worked fine, although its ugly unless its in the default template, or one at least provided with the plugin.
the change is only adding a call to an abstract method that lets you add extra variables to the velocity context at the end of the createAndPopulateContext method in the AbstractGenerator
and in the Generator implement this as
context.put("fulldependencies", config.getPackagedJnlpArtifacts());
I will attach a patch for this just in case its usefull to anyone
Patch to expose the dependencies (as maven objects not strings) to the VelocityContext
I'm also interested in this issue being fixed. It's making things very tricky with regards to being able to deploy a SWT application...
EDIT: And I'm quite surprised that this issue has been around for 3 years without being fixed.
All I need is some simple way of being able to do the following:
Assuming I have a set of profiles that load the Linux JARs for SWT and the Windows JARs for SWT depending on the operating system of the developer, I want to be able to manually load all the dependencies for the operating system(s) I'm targeting.
I then need to be able to specify (somehow) that those JARs should be added to their own resource elements, with a specific OS/Arch attribute.
e.g.
I have the following dependencies:
<dependency>
<groupId>org.eclipse.swt.gtk.linux</groupId>
<artifactId>gtk-x86</artifactId>
<version>3.3.0-v3346</version>
</dependency>
<dependency>
<groupId>org.eclipse.swt.win32.win32</groupId>
<artifactId>win32-x86</artifactId>
<version>3.3.0-v3346</version>
</dependency>
I want most of my dependencies to be listed as normal, but I want some way (I'm not very fussy - as long as it's possible, I don't care about the details
) of turning the above JARs into the following:
<resources os="Linux" arch="i386">
<jar href="gtk-x86-3.3.0-v3346.jar" />
</resources>
<resources os="Windows">
<jar href="win32-x86-3.3.0-v3346.jar" />
</resources>
Ideally, whatever method I use should be compatible with the jnlp-single goal.
As it stands now, I'm not sure I'm going to be able to use Maven to build this project, which is a real shame because I really like Maven, but if I can't get it to include some OS-specific deps in the right way, it's not all that useful to me.
Could a possible workaround be to have architecture specific dependencies inside <profile>'s: http://maven.apache.org/guides/mini/guide-building-for-different-environments.html,
possibly triggered by operatingsystem or by hand (-PnameOfProfile)?
Deployment of a specific version could be done with a http://maven.apache.org/plugins/maven-deploy-plugin/examples/deploying-with-classifiers.html.
Managed to work around it via this very simple (and really just plain bad) method:
Create a custom velocity template.
Instead of using $dependencies, use $depencies.replaceAll("<jar href=\"$
{jar1}\" />", "") for each JAR I need removed from the default deps list.
Then I can happily hard-code them in where I need them.
Is this ideal? Hell no. Does it do exactly what I need it to? Yes, it does. Having said that, I might be interested in trying to get some development done to make this better, given that I'm using it, and development seems to have halted.
Using the patch I submited before, and this new template, you can have a webstart for the various architectures and SOs
template: jnlptemplate.vm
If some of you are instereded I started an alternate plugin that use the template velocity to drive which jar to copy/sign/...
The plugin is not finished (I would like to integrate proguard, and need some doc).
But I already use it to deploy in my customer some jnlp and applet, I could deploy the plugin in a public repository if you're interested.
the source : http://github.com/davidB/maven-basicwebstart-plugin/tree/master
In the patch for the jnlptemplate.vm I use href="$
{dependency.file.name}" instead of href="$
{dependency.artifactId}-$
{dependency.version}-$
{dependency.classifier}.jar". This solves an issue where the project artifact (if built as part of a project) does not have a version number added to the file.
For my projects (where we only run only Windows app) I've set up in the template the following code (inspired by Andrew Thorburn comment):
$dependencies.replaceAll("<jar href=\"lib/dll", "<nativelib href=\"lib/dll")
instead of $dependencies.
This cause every dependency whose name start with dll to be set as a nativelib.
For us, using velocity also works great. A general replacing of jar with nativelib does not work since javaws doesn't seem to like mixing these elements in the same resource definition.
We use a naming scheme of the jar files with native libraries to support multiple platforms. All our native libs contain a common identifier and a platform specific identifier. The resources segment usually looks something like this:
<resources> <java version="1.6+" initial-heap-size="128m" max-heap-size="512m" /> #foreach($dependency in $dependencies.split("\n")) #set($dependency = $dependency.trim()) #if ($dependency.length() > 0 && $dependency.indexOf("native") == -1) $dependency.replace("/>", ' download="eager"/>') #end #end <property name="jnlp.packEnabled" value="true"/> </resources> <resources os="Windows" arch="x86"> #foreach($dependency in $dependencies.split("\n")) #if ($dependency.indexOf("win32") >= 0) #set($dependency = $dependency.trim()) $dependency.replace("<jar", "<nativelib").replace("/>", ' download="eager"/>') #end #end </resources> <resources os="SunOS" arch="x86"> #foreach($dependency in $dependencies.split("\n")) #if ($dependency.indexOf("sunx86") >= 0) #set($dependency = $dependency.trim()) $dependency.replace("<jar", "<nativelib").replace("/>", ' download="eager"/>') #end #end </resources>
I'd like to do something about this issue, Could you attach here a example project about this feature.
IMHO Doing some logic in the template is not a very good idea, it would be more cool to have a real special configuration for the nativelib support DYT ?
That sounds very nice. I will attach an example project on this issue in a few days.
Hi, it really rocks that this project is having some development done again ![]()
We are still using what I mentioned in a previous comment https://jira.codehaus.org/browse/MWEBSTART-8?focusedCommentId=179525&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-179525 that is exposing the maven dependencies to the template, and then using some logic there to see what goes in each part of the jnlp. I think something like this is important so that people can implement their own solution if the one chosen by the plugin doesn't match their needs.
One thing that I would like to propose is that the natives should already be jars with some classifier that indicates that they are natives, their OS, and optionally the architecture. We already have a couple of libs that are used a lot for game development (lwjgl an opengl binding for java, and jinput a input controller lib for java) that use this naming convention.
What we do is add a classifier like "natives-$
{OS}" and optionally "natives-${OS}-$
{arch}" this is quite nice because it allows you to process the dependencies depending on the scope you need, all dependencies, dependencies by os, etc.
One important part of using existing jar dependencies, instead of having the deps be directly the dll, .os, etc is that lots of times native dependencies are made of more than one native file, so a jar is the natural way to do that.
Right now we have the logic in our template, but I agree that having it in the plugin would be nice, what I think would be the right approach is having some mapping logic that can be redefined by the user, but has a reasonable default
something like
in the plugin config <natives> <prefix>natives</prefix> <mapping> <OS> <resourceOS>Windows</resourceOS> <classifiers> <classifier>windows</classifier> </classifiers> </OS> <OS> <resourceOS>Linux</resourceOS> <classifiers> <classifier>linux</classifier> </classifiers> </OS> <OS> <resourceOS>Mac</resourceOS> <classifiers> <classifier>mac</classifier> <classifier>osx</classifier> </classifiers> </OS> </mapping> </natives>
This should have of course a reasonable default, that would work for most people, but having it configurable, would allow someone to be able to use some dependency that uses a different naming convention.
The example xml is not an exact syntax proposal, but just the things that someone should be able to configure.
Another thing that might be useful, is being able to add some dependency, to an OS in the jnlp, by mentioning the dependency groupid, and artifact in the config, this would allow people to add a dependency, that doesn't use the naming convention at all
in the plugin conifg <forcedNatives> <OS> <name>Windows</name> <natives> <native> <groupId>com.orgname.proy</groupId> <artifact>proynatives</artifactId> </native> <native> <groupId>com.orgname2.proy2</groupId> <artifact>proy2natives</artifactId> </native> </natives> </OS> </forcedNatives>
Usually this would not be used, and is just to be able to add native dependencies that are not using the naming convention.
Just as an example of what we use now
this is the jnlptemplate for one of our projects https://github.com/gemserk/prototypes/blob/master/prototypes-desktop/src/main/jnlp/jnlptemplate.vm
You can see that we have "fulldependencies" as a variable with the content of config.getPackagedJnlpArtifacts() and we use logic in the template to filter the jars by os, we changed how we named the os in some natives so you see an OR when checking some OSs.
Another thing that you can see in this example, but that would be for another issue is that we generate webstart and jnlp applet info, with a comment on the lines that say if it is one or the other, after we generate the jnlp, we use an external script, to create two jnlp files, one for jnlp applets, and one for webstart.
Hope you like our ideas, we would love to help to get this done.
Rubén Garat
Gemserk Studios
I needed the native library support in webstart plugin while developing an swt appliation.
I have added the feature for jnlp-download-servlet goal which can be easily be extended to other goals.
The configuration looks like following:
<jnlpFile>
........
<nativeDependencies>
<nativeDependency>
<os>Linux</os>
<arch>x86</arch>
<nativeResources>
<nativeResource>
<resourceType>nativelib</resourceType>
<groupId>${swt.groupId}</groupId>
<artifactId>org.eclipse.swt.gtk.linux.native.x86</artifactId>
<version>${swt.version}</version>
</nativeResource>
<nativeResource>
<resourceType>jar</resourceType>
<groupId>${swt.groupId}</groupId>
<artifactId>org.eclipse.swt.gtk.linux.x86</artifactId>
<version>${swt.version}</version>
</nativeResource>
</nativeResources>
</nativeDependency>
<nativeDependency>
<os>Linux</os>
<arch>x86_64</arch>
<nativeResources>
<nativeResource>
<resourceType>jar</resourceType>
<groupId>${swt.groupId}</groupId>
<artifactId>org.eclipse.swt.gtk.linux.x86_64</artifactId>
<version>${swt.version}</version>
</nativeResource>
</nativeResources>
</nativeDependency>
</nativeDependencies>
.......
</jnlpFile>
Inside jnlp template we need to set
$
{nativeDependencies}and the output for above example in generated jnlp file looks like following:
<resources os="Linux" arch="x86"> <nativelib href="library/org.eclipse.swt.gtk.linux.native.x86.jar" version="3.8"> <jar href="library/org.eclipse.swt.gtk.linux.x86.jar" version="3.8"> </resources> <resources os="Linux" arch="x86_64"> <jar href="library/org.eclipse.swt.gtk.linux.x86_64.jar" version="3.8"> </resources>
The functionality will check the declared native libs in
<jarResources>
........
</jarResources>
as well and their transitive dependencies. If the declared native lib exists, their declaration won't be in
${dependencies} substitution but only in ${nativeDependencies}
.
What do you all think?
I will post a patch after some refinement.
Good thing that someone needs this again.We will try if you'd like to find a way out to resolve this soon (until 10 days I am a bit off the grid for this plugin).
So feel free to offer a patch, any good idea is welcome ![]()
We need this functionality. I was just going to hand write the native stuff into the template and upload my old hand-rolled native jars into maven unless this is fixed soon
In the meantime I applied some of the patches that were posted here earlier, but I think most of them stopped working under maven 3.0. Too bad.
Patch for fix proposed in following comment: https://jira.codehaus.org/browse/MWEBSTART-8?focusedCommentId=306198&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-306198
The architecture value (arch tag) can be semi colon separated to generate same dependencies declaration for different architectures without repeating whole block. For example:
<os>Windows</os> <arch>amd64;x86_64</arch>
I have extended JarResourcesGeneratorTest.testGetDependenciesText() test case to cover the generation of native libraries jnlp declaration.
Are you facing any issues with Maven 3.0. I've tested the changes with Maven 3.0.2 via m2eclipse plugin.
Just came to my mind, the patch includes the fix for a bug that i encountered while using this plugin in a project. To summarize, the plugin wasn't substituting maven properties in jnlp template with values passed at execution time via -D, rather it picks up property value defined in pom.xml. -D ideally must override the property value defined inside pom.
Actually it was one of the oldest patches that I used, the ones that were orignally attached to this defect.
About the arch node, isn't it more standard in maven to use a wrapping <archs> element and then list all the single instances as children?
That would be more readable (but I suppose more code).
I completely agree. Having <archs> tag is the ideal way to implement the functionality. The reason i implemented it this way is because i came across the multiple archs use-case after i had implemented native lib functionality completely. I was under tight time constraint and saw colon separated values approach as quickest to implement.
Thanks for pointing it out. I will implement the <archs> approach and submit a patch soon.
I just tried patch 8d but I'm getting
"The following error occurred attempting to generate the JNLP deployment descriptor: java.lang.ClassCastException: org.codehaus.mojo.webstart.JarResource cannot be cast to org.codehaus.mojo.webstart.NativeResource"
When I have
<jnlpFile>
....
<nativeDependencies>
<nativeDependency>
<os>Linux</os>
<arch>x86</arch>
<nativeResources>
<nativeResource>
<resourceType>nativelib</resourceType>
<groupId>org.rxtx</groupId>
<artifactId>rxtx-linux64</artifactId>
<version>$
</version>
</nativeResource>
</nativeResources>
</nativeDependency>
</nativeDependencies>
Ok, I've done a load of work and managed to get the native lib stuff working, but at the moment my changes are based on the 8d patch, but with a load of extra debug and change parts of the existing code to use generics as it helped me chase down the type miss-match issues. I have also for now disabled adding non-native dependencies for your native dependencies as otherwise you end up adding these as native within the jnlp
8d patch only contains changes for jnlp-download-servlet goal. The exception that you have reported comes when using other goals, right? I guess you have made changes for the other goals as well. Great that you have used generics to enforce type safety. Please share the patch whenever you can. Thanks
My attempt to take the 8d patch, apply it then fix the problems I was seeing. Not perfect, but does at least not ClassCast ![]()
I mentioned in my earlier post as well that this patch is only for jnlp download servlet goal and can be extended to others.
Class Cast exception is inevitable in the 8d patch if one uses the <nativeDependencies> declaration in other jnlp goal configurations as the implementation is missing.
Thanks for sharing the patch.
I was using the download servlet. The issue is that you assume that the native libs have no dependencies or if they do, that they are also native. If they are not, you get a ClassCast. I have worked round the issue by dealing with this by downloading the native stuff in it's own method and ignoring any transitive deps of these native resources
Packaging the .dll automatically in a jar should not be a required step.
In our case, we are, for simplicity, pre-packaging a set of dll's in a jar and deploying that jar to our maven repo. I need to specify that dependancy jar as a nativelib, without any special processing except to mark it as nativelib in the jnlp file.