is it possible to enrich a Swing-based JApplet (running in a web browser) with JavaFX content that works for Java7 clients? I tried the following things, but without success:
a) Swing JApplet: If I try to add a JFXPanel to a JApplet I get java.lang.ClassNotFoundException: javafx.embed.swing.JFXPanel at runtime.
b) Swing JApplet including javafx_version parameter (version 2.2+, see generated APPLET tag when using dtjava.embed() of the deployment toolkit): Adding a JFXPanel to a JApplet results in java.lang.ClassCastException: SwingInterop cannot be cast to javafx.application.Application at runtime.
c) JavaFX Applet (javafx.application.Application): It seems that swing content can only be shown in a new JFrame (as shown in the official Oracle example at http://www.oracle.com/technetwork/java/javase/overview/javafx-samples-2158687.html) but not in a JavaFX Applet (javafx.application.Application) itself. SwingNode introduced with Java8 would obviously be the way to go but I didn't found a reliable alternative for Java7.
Is there any way to get option a) running by adding the jfxrt.jar to the classpath (as option b) is obviously doing somehow)?
Oracle have a detailed tutorial on JavaFX in Swing Applications for Java 7.
I suggest you follow that tutorial.
Note that packaging jfxrt.jar with the application is not necessary, and is not recommended (for all the reasons you have in your comment).
Just copy and pasting samples from the Oracle tutorial in case their link goes dead.
Using JavaFX Ant Tasks to Package a Swing Application with Integrated JavaFX Content (key is toolkit="swing"):
<taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
uri="javafx:com.sun.javafx.tools.ant"
classpath="${javafx.sdk.path}/lib/ant-javafx.jar"/>
<fx:jar destfile="dist-web/ColorfulCircles.jar">
<fx:application refid="myapp"/>
<fileset dir="build/classes/">
<include name="**"/>
</fileset>
</fx:jar>
<fx:deploy width="800" height="600" outdir="dist-web"
outfile="SwingInterop">
<fx:info title="Swing Interop"/>
<!-- Mark application as a Swing app -->
<fx:application id="myapp"
mainClass="swinginterop.SwingInterop"
toolkit="swing"/>
<fx:resources>
<fx:fileset dir="dist-web" includes="SwingInterop.jar"/>
</fx:resources>
</fx:deploy>
If you aren't using the JavaFX packaging tools, you can still use JavaFX, just edit your jnlp file, to set up the resources with the jfx namespace:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0"
xmlns:jfx="http://javafx.com"
href="SwingAppWithJavaFXContent.jnlp"
...>
....
<resources>
<j2se version="1.7.0_06+"
href="http://java.sun.com/products/autodl/j2se"/>
<jfx:javafx-runtime version="2.1+"
href="http://javadl.sun.com/webapps/download/GetFile/
javafx-latest/windows-i586/javafx2.jnlp"/>
</resources>
...
</jnlp>
And in your html page, you embed the Java deployment toolkit and make it JavaFX aware:
<html>
<head>
<SCRIPT src="http://java.com/js/dtjava.js"></SCRIPT>
<script>
function launchApplication(jnlpfile) {
dtjava.launch(
{ url : jnlpfile },
{
javafx : '2.2+',
toolkit: 'swing'
},
{}
);
return false;
}
</script>
</head>
<body>
<h2>Test page</h2>
<a href='SampleApp.jnlp'
onclick="return launchApplication('SampleApp.jnlp');">Click</a>
to launch test app.
</body>
</html>
I want to show JavaFX content (a JFXPanel) within the area of a JApplet within a browser window.
That is exactly what this answer explains how to do (at least the packaging portion), the JFXPanel javadoc describes the rest.
For an executable example of embedding JavaFX in a Swing Applet, see the JavaFX "SwingInterop" sample code. You can download the SwingInterop sample code from the "JDK 8 Demos and Samples" link off of the Java download page. A Java 7 equivalent would also be available from the Java 7 download archives.
Related
The end goal is to provide application client downloads using Java webstart from Glassfish 4.
I've been trying to get this working for 3 days, researching every method I can find and no matter what I try, webstart is blocked.
Exception list. Doesn't work.
Adding the certificate as a trusted certificate. Doesn't work.
Sandbox which doesn't need any permissions. Doesn't work.
Updating Java. Doesn't work.
I can't seem to find the deployment rule sets option but this sounds like something that needs full windows server integration etc.
There is no medium option in the Java console security settings as I am using java 8.0.31.
Simple test app that has nothing but static main void which prints a message to command line. Cannot get it to work...
It is starting to drive me crazy that it is impossible to develop anything using webstart, the only options I can see are purchasing a certificate for local development or totally dropping webstart...
How I added the certifacte to my machine - the certificate is shown in my Java console.
Here is the simple scenario I cannot get working:
package com.cbprogramming;
import javafx.application.Application;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
System.out.println("Test");
}
public static void main(String[] args) {
launch(args);
}
}
I then used IntelliJ Idea to create a JavaFX application that packages it including the webstart jar file, JNLP file and html web page including custom manifest fields for permissions: sandbox and codebase.
The JNLP file, I also tried with the security and permissions tags, both all-permissions and sandbox.
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0" xmlns:jfx="http://javafx.com" href="WebstartTest.jnlp">
<information>
<title>Webstart Test</title>
<vendor>Testing</vendor>
<description>A Java Webstart testing app</description>
<offline-allowed/>
</information>
<resources>
<jfx:javafx-runtime version="8.0+" href="http://javadl.sun.com/webapps/download/GetFile/javafx-latest/windows-i586/javafx2.jnlp"/>
</resources>
<resources>
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
<jar href="WebstartTest.jar" size="1190" download="eager" />
</resources>
<security>
<all-permissions/>
</security>
<applet-desc width="600" height="400" main-class="com.javafx.main.NoJavaFXFallback" name="WebstartTest" >
<param name="requiredFXVersion" value="8.0+"/>
</applet-desc>
<jfx:javafx-desc width="600" height="400" main-class="com.test.Main" name="WebstartTest" />
<update check="background"/>
</jnlp>
And the manifest file:
Manifest-Version: 1.0
permissions: sandbox
codebase: file:///d:/test/
JavaFX-Version: 8.0
Class-Path:
Created-By: JavaFX Packager
Main-Class: com.test.Main
Name: com/test/Main.class
SHA-256-Digest: 8BK5m/ojirCK/QEx8Oe+9z/L6P8JXin0CMDK4R2mkAI=
I have added the jnlp, jar and html files to the exceptions list, I've tried both with file:// and file:///, I've also tried adding the glassfhish URL to the exception list, http and https...
I am developing on a Win 8.1 pro machine using Jdk 8.0.31.
Every forum I have read users are saying any one of these options fix their problem. What am I doing so wrong?!? Is 8.0.31 broken? Or is webstart just not worth using?
Here is what I found incase others find it useful.
It looks like Glassfish 4.1 has a webstart bug when using Java 7 update 25 or later (currently 8.0.31). The workaround is to use an older version of Java.
I never could get the java console exceptions list to work.
Adding the certificate as trusted let webstart work from a local file/html file but it still didn't work through glassfish.
The tags needed to be removed from jnlp files now that they are in the jar manifest file or the application was blocked, these tags are added automaticlly by glassfish and intellij JavaFX packager.
Another thought is to setup a local certificate authority and add it as trusted through the java console - this way it isn't a self signed certificate.
Also, to get a glassfish application client debugging in IntelliJ:
Create a batch file: start "name" cmd /c "<installdir>\glassfish\bin\appclient.bat -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -client <dir>\TEMPSClient.jar"
Create a remote debugging configuration and set it to run the created script using the external tool in the before launch section.
This uses the default ports etc. for remote debugging, and will run the application jar in the glassfish client container before attaching the debugger to it. To get console output, redirect stdout and stderr to a log file and attach the log file to your remote debug configuration.
I first tried using the embedded ACC but couldn't get that working (copy/paste from docs has functions that don't even exist...). It would be great if someone knows of a good tutorial for using the embedded ACC.
I have done a few Java programs but this is the first one that I'm trying to run as an applet so I might have some basic error.
I compiled all the classes and put them together in a jar file called final.
I followed a few tutorials to make a JNLP file that I called jnlp (yeah, I know, I'm very original:) and on which I called to my jar file and I called the JNLP file from an HTML file.
Those are the last lines of the java console output: (before them, the console is filled with my JNLP file)
at sun.plugin2.applet.JNLP2Manager.loadJarFiles(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
preloader: Added pending event 2: ErrorEvent[url=null label=JNLP not an applet, nor a JavaFX application cause=JNLP not an applet, nor a JavaFX application
Here is the JNLP file:
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="" href="jnlp.jnlp">
<information>
<title>Encryption Software</title>
<vendor>Atlantis Atlantis</vendor>
<icon href="encrypt_logo.jpg"/>
<offline-allowed/>
</information>
<resources>
<!-- Application Resources -->
<j2se version="1.6+" href=
"http://java.sun.com/products/autodl/j2se"/>
<jar href="final.jar"
main="true" />
</resources>
<application-desc
name="Encryption Software"
main-class="EncryptApplication"
width="500"
height="300">
</application-desc>
<update check="background"/>
</jnlp>
Here is the JS used to launch the applet:
<script src="https://www.java.com/js/deployJava.js"></script>
<script>
var attributes = {code:'', width:500, height:500};
var parameters = {jnlp_href: 'jnlp.jnlp'};
deployJava.runApplet(attributes, parameters, '1.6');
</script>
Is the EncryptionApplication really an applet? To be an applet it must extend Applet or JApplet.
If it is not an applet, it cannot be embedded in HTML.
If it is an applet, the JNLP must declare it as such, so:
<application-desc
name="Encryption Software"
main-class="EncryptApplication"
width="500"
height="300">
</application-desc>
Should be:
<applet-desc
name="Encryption Software"
main-class="EncryptApplication"
width="500"
height="300">
</applet-desc>
Tips
Be sure to check the JNLP using JaNeLA.
Avoid applets like you might avoid the plague. They were always a complete PITA and with recent security updates, have only become more so. See Why CS teachers should stop teaching Java applets for my take on the matter.
It is possible to launch an application (e.g. a JFrame based app.) from a link using Java Web Start. They will be subject to the same (very strict) security requirements of applets, but have none of the applet specific problems (see link in previous point for details).
As mentioned by #ElliottFrisch, it is best to include a valid value for the code attribute. There are circumstances in which it can be left out, but I won't get into that right now..
Hi i'm creating an application in javafx 2.2 and while compiling a native bundle (EXE) I can see that in the Runtime I miss a library I need.
MyApp\runtime\jre\lib\ext\sunjce_provider.jar
I try adding it like this in my build.xml
<fx:deploy width="${javafx.run.width}" height="${javafx.run.height}"
nativebundles="exe"
outdir="${basedir}/${dist.dir}" outfile="${application.title}">
<fx:application name="${application.title}" mainClass="${javafx.main.class}"/>
<fx:resources>
...
<fx:fileset dir="${platform.home}/jre/lib/ext" includes="sunjce_provider.jar"
type="data"/>
</fx:resources>
<fx:info title="${application.title}" vendor="${application.vendor}"/>
</fx:deploy>
But that only leaves it at
MyApp\app\sunjce_provider.jar
Is there a way to accomplish this?
Including Application Libraries
This section shows how to include standard jars which your application relies upon.
Sample build.xml snippet from the JavaFX ant task reference, the key line is <fx:fileset dir="dist" includes="lib/*.jar"/>:
<!-- Expect definition of JavaFX ant tasks is already imported -->
<fx:jar destfile="dist/application.jar">
<!-- Details about application -->
<fx:application name="Sample JavaFX application"
mainClass="test.MyApplication"/>
<!-- Define what auxilary resources are needed -->
<fx:resources>
<fx:fileset dir="dist" includes="lib/*.jar"/>
</fx:resources>
<!-- What to include into result jar file?
Everything in the build tree -->
<fileset dir="build/classes"/>
<!-- Customize jar manifest (optional) -->
<manifest>
<attribute name="Implementation-Vendor" value="Samples Team"/>
<attribute name="Implementation-Version" value="1.0"/>
</manifest>
</fx:jar>
Modifying the JRE components
This section shows you how to customize the the Java runtime components that are bundled with your application.
See the Java Deployment blog on including the sun jce provider in native packaging (noted in question: sunjce_provider.jar in jre for standalone javafx application).
Relevant sections (copy and pasted from the blog entry) are:
If you are using packaging tools to produce an installable package there could be a need to tweak the application image before it is wrapped into the installer. Why? For example you may want to sign the application, so it does not appear to be untrusted to the OS (for example to please Mac OS X Gatekeeper).
Also by default a self-contained application does not contain full copy of Java Runtime. We only include set of mandatory components. Part of the reason why this approach was taken is that we want to reduce the package size. However, there are situations where your application may depend on these optional components and in that case you will need a way to add them to the private runtime. For example https connections will not work if jre/lib/ext/sunjce_provider.jar is missing.
Currently this can be achieved by providing a custom config script that is executed after application image is populated. Like in the example above with the icon, you need to enable verbose output to find the name of the script file and then drop it to the location where packaging tools will find it. Note that scripting language is platform specific too. Currently we only support shell for Mac/Linux and Windows Script on windows.
How do you find out where the application image is located? Currently custom scripts are run in the directory where config files are stored but application image can be accessed using relative platform specific path. You can derive this path from verbose output or by setting environment variable JAVAFX_ANT_DEBUG to true to keep intermediate build artifacts.
Here is sample script (contributed by John Petersen) you can use to add jre/lib/ext/sunjce_provider.jar to the application package of MyApp on the Windows platform. Script using Javascript but you could also use VBScript for Windows scripting.
<?xml version="1.0" ?>
<package>
<job id="postImage">
<script language="JScript">
<![CDATA[
var oFSO = new ActiveXObject("Scripting.FileSystemObject");
var oFolder = oFSO.getFolder(".");
var from = oFolder.path + "\\MyApp\\app\\sunjce_provider.jar";
var to = oFolder.path + "\\MyApp\\runtime\\jre\\lib\\ext";
if (!oFSO.FolderExists(to)) {
oFSO.CreateFolder(to);
}
to += "\\";
oFSO.CopyFile(from, to);
]]>
</script>
</job>
</package>
I'm trying to run my JNLP within an HTML page, but the java plugin does not run the JNLP, runs only the Applet.
Here is my code:
<applet width="800" height="500" codebase="http://127.0.0.1:8888/applets/"
code="br.com.app.server.utils.CompatibilityApplet"
archive="CompatibilityApplet.jar">
<param name="jnlp_ref" value="http://127.0.0.1:8888/applets/testehellojws.jnlp">
</applet>
Thanks.
[EDIT]
An example:
http://java.sun.com/javase/ja/6/ea/6u10/plugin2/jnlp/CompatibilityApplet.java
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="6.0+" codebase="http://127.0.0.1:8888/applets/" href="testehellojws.jnlp">
<information>
<title>App Hello</title>
<vendor>My App Jnlp.</vendor>
<homepage href="http://127.0.0.1:8888/Home.html"/>
<description>My App Jnlp</description>
<description kind="short">Appr</description>
<icon href="images/icone.jpg"/>
</information>
<resources>
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
<jar href="hello.jar" main="true"/>
</resources>
<application-desc main-class="br.com.app.server.HelloJWS"></application-desc>
</jnlp>
Please edit your question and just let me know it is edited.
OK
Did you miss the part about the documentBase?
I didn't.
I would recommend removing the space in the applet name attribute.
Done
Can you run any other JNLP embedded applets? E.G. the small (sand-boxed) GIFanim applet at my site?
Yes
What info. do you get reported from here?
java.vendor: Sun Microsystems Inc.
java.version: 1.6.0_26
os.name: Windows 7
os.version: 6.1
<application-desc main-class="br.com.app.server.HelloJWS"></application-desc>
That is the descriptor for a Java application (as opposed to an applet). For an applet, use something more like..
<applet-desc main-class="br.com.app.server.HelloJWS"></applet-desc>
Note:
Even that is not a correct descriptor for an applet, which must explicitly state a documentBase, name, width & height. See the applet-desc section of the JNLP File Syntax for more details.
It must (of course) be an applet. It is not possible to 'embed' an application into a web page using this technique.
JNLP and the Java Plug-In (required for both applets and web start) was deprecated and removed from the API in Java 9.
Your jnlp_ref should probably be an absolute URI, e.g. http://127.0.0.1:8888/applets/testehellojws.jnlp
Also there is a stray space at the start of your code value (though this is probably not the cause of your problem.)
Checking on a related post, I decided to test the tag
<OBJECT>
.
I thought that this would not work with JNLP, so we had tested before.
After changing
<APPLET>
to
<OBJECT>
and referencing my jnlp file as a parameter, it worked!
The browser ignores the code and archive parameters and run my JNLP.
thanks.
Try to remove [archive="CompatibilityApplet.jar"]
My applet doesn’t see the external libraries. Everything works using the appletviewer, but not using the browser. I’ve put in my “test_applet” folder the jar (TreC-Vis.jar) containing the applet classes, four jar libraries used by TreC-Vis and the html file with the following applet tag:
<applet code="gui.Gui" archive="TreC-Vis.jar,postgresql-8.4-701.jdbc4.jar,postgis_1.5.0.jar,jfreechart-1.0.13.jar,jcommon-1.0.16.jar" width="1024" height="768"> </applet>
Java console gives me a java.io.FileNotFoundException for each of the four jar libraries.
I specify that I exported TreC-Vis.jar from the corresponding Eclipse project, in which I put these libraries in a “lib” folder at the same level of the “src” package.
What’s wrong with the applet tag I wrote?
Reading the tutorial here
http://download.oracle.com/javase/tutorial/deployment/jar/downman.html
I’ve been considering the possibility to put everything, applet and libraries, in one jar as a solution, but I would need some example of the “custom code” mentioned in the Note.
Thanks in advance.
My applet doesn’t see the external libraries. ..They are just native libraries, .. .class files ..
OK. If then, you mean 'natives' as in files of type .dll, .so etc., that is problematic for an applet in that they cannot use the natives unless they are already installed in the appropriate directory of the user system.
Having said that, recent developments allow us to deploy an embedded applet using Java webstart (JWS). JWS makes use of natives easy. Simply put them in the root of a Jar file and add them to a nativelib element in the (XML based) launch file (file type .jnlp).
Even better, JWS can separate the downloads into resources for different operating systems, so Windows gets the .dll natives, while *nix get the .so natives.
JWS offers many more useful features, but the important thing here is that they can make natives available to applets.
Use of native libs in an applet, requires the applet to be trusted.
jar cfm MyApplet.jar MyManifest.txt MyPackage1 MyPackage2 MyPackage3
This was the line I was looking for. This way I've put in my manifest the classpath of the external libraries.
Here is my code and how I have used native libraries in that. It does work in Windowes but it doesn't work in Linux and I receive
access denied("java.lang.RuntimePermission""loadLibrary.hello")
Here is my JNLP:
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="" href="">
<resources>
<!-- Application Resources -->
<j2se version="1.7+"
href="http://java.sun.com/products/autodl/j2se"/>
<jar href="applet.jar" main="true" />
<nativelib download="eager" href="libhello.jar"/>
</resources>
<applet-desc
name="Math Applet"
main-class="NativeHelloApplet"
width="10"
height="1">
</applet-desc>
<update check="background"/>
</jnlp>
My Applet:
import java.security.*;
import javax.swing.*;
public class NativeHelloApplet extends JApplet
{
public native String displayHelloWorld();
public native int initPKE (int[] retVal);
public NativeHelloApplet() {
}
public void init()
{
// privileged code goes here, for example:
System.loadLibrary("hello");
getContentPane().add(new JLabel("Test"));
getContentPane().add(new JLabel(displayHelloWorld()));
}
}
My native .c code :
#include <jni.h>
#include "NativeHelloApplet.h"
#include <stdio.h>
JNIEXPORT jstring JNICALL
Java_NativeHelloApplet_displayHelloWorld(JNIEnv *env, jobject obj)
{
return (*env)->NewStringUTF(env,"Hello world!\n");
}
My HTML page:
<Html>
<Head>
<Title>Java Example</Title>
</Head>
<Body>
This is my page<br>
Below you see an applet<br>
<br>
<script language="javascript" type="text/javascript" src="deployJava.js"></script>
<script>
var attributes = {
id: "sswSignApplet",
code: "NativeHelloApplet",
width: 300,
height: 60
};
var parameters = {jnlp_href:"launch.jnlp"}; <!-- Applet Parameters -->
var version = "1.6"; <!-- Required Java Version -->
deployJava.runApplet(attributes, parameters, version);
</script>
</Body>
</Html>
libhello.jar contains the shared object of my native code and is located on the same folder as html and jnlp.
It works in windows when I put hello.jar(containing hello.dll) in resource section but in Linux I received the mentioned error.