Testing if Quicktime and Java are installed? - java

In Javascript how can I test if the user has the quicktime plugin and java plugins installed?

For Java, you can use navigator.javaEnabled(). Or you can look here: http://www.pinlady.net/PluginDetect/JavaDetect.htm
For QuickTime, you can do:
var QtPlugin = navigator.plugins["Quicktime"];
if (QtPlugin) {//QuickTime is installed}
See here: http://javascript.internet.com/miscellaneous/check-plugins.html

This of course does not work in IE. The only way to check plugins in IE is using VB script, and it is very strange and messy. You can only test for specific plugin versions, for example, "quicktime" won't cut it. You have to specify the version, which is not published for versions older than 5, and I can't find a reference for version 7

The above examples haven't got the answer to the QuickTime part of your question, so here's what I'm writing right now even though the question has been closed and is a little old.
var p = navigator.plugins;
var qtcheck = 0;
for (i=0;i<p.length;i++) {
if (p[i].name.match(/QuickTime/) != null) {
qtcheck++
}
}
if (qtcheck > 0) { // do nothing, QuickTime is intalled }
else {
videos = document.querySelectorAll('object[type="video/quicktime"]')
// use .getElementById instead if there are multiple videos
// replace them with document.createElement('img')
For a more comprehensive and foolproof method i.e. without worry of a plug-in being renamed for whatever reason, you can check within the array of MimeTypes for type="video/quicktime" which is the ultimate answer of whether the object will be supported (or if you're not using the QT video, whatever else you're using it for instead).
This means creating a loop inside the loop through the plugins instead, but is a more firm verification than just a string match:
function checkQT() {
var p = navigator.plugins;
var QT = false; // assume you don't have it
for (i=0;i<p.length;i++) {
for (j=0;j<p[i].length;j++) {
if (p[i][j].type == "video/quicktime") {
QT = true;
return true;
}
else continue;
return false;
}
}
}
I searched around online and found a bunch of great IE fallback scripts here (not sure if this paste service code is going to persist so I gisted it for posterity), from which I took the QuickTime one:
function IEhasQT() {
if (!window.ActiveXObject) return false;
try { if(new ActiveXObject("QuickTime.QuickTime")) return true; }
catch (e) {}
try { if (new ActiveXObject('QuickTimeCheckObject.QuickTimeCheck')) return true; }
catch (e) {}
return false;
}
I tested some others and they just didn't work - catching the exceptions is important.
If you're doing what I'm doing (QuickTime fallback to a gif animation) you might want to take the attributes of the video to provide to the image (or whatever else you're using). The downside to this is that you have to couple it to an onscroll as well as onload (or use Jquery) as the browser is liable to try and find the element before the DOM has loaded no matter how you try and avoid it.
If anyone else reading this is looking for a similar answer, the code to do so is
function noQTfallback() {
var vid1 = document.getElementById("<insert your object id>");
var vid1gif = document.createElement('img');
vid1gif.setAttribute("src","<insert your URL source>");
vid1gif.setAttribute("style",vid1.getAttribute("style"));
document.getElementById("<...>").replaceChild(vid1gif, vid1);
}
function IEhasQT() {
// as above
}
function checkQT() {
// as above
}
function QTbackup(){
if (!checkQT() && !IEhasQT()) {
noQTfallback();
}
}
window.document.body.onload = QTbackup;
window.onscroll = QTbackup;
Oddly, you can have multiple versions of QuickTime installed, my Chrome browser on Windows has 7 copies... Luckily I have a Chromebook which doesn't have QT plug-in either installed or available, so I'm checking and seeing what works to distinguish it, this is the best I've come up with.
I never understood why testing was so important until looking at everyone's awful code on this online, incredible. I know no one cares about IE but basic things like || instead of && are just bad to leave lying around for other developers to reuse.
I've checked this on Windows, Linux and Android (IE and Chrome). The onscroll gives a bit of a jump but without Jquery or some other framework it's unavoidable I guess (and beats "plug-in not supported" !

Related

Correct way to check if JavaFX MediaPlayer can play a file

Currently, this is how I check if a file is playable through the JavaFX MediaPlayer, since it's the way it is done internally.
import static com.sun.media.jfxmedia.MediaManager.canPlayContentType;
import static com.sun.media.jfxmediaimpl.MediaUtils.filenameToContentType;
public boolean isPlayable(String filename) {
return canPlayContentType(filenameToContentType(filename));
}
the problem is that the packages that contain these Methods "are not API" and not accessible on Java 9 anymore. I know that there are workarounds, but I wonder if there is an actually correct, future-proof way of doing this?
I want this method to populate a Library with all the playable content within a directory:
Files.find(folderPath, Integer.MAX_VALUE, (path, attr) ->
attr.isRegularFile() && isPlayable(path.toFile().getName()))
.forEach(path -> addSong(path));
I went through the documentation of javafx.media module for the sake of finding any such built-in API and was unable to find one.
A look at the existing Implementation of filenameToContentType(String filename), which is somewhat:-
if (extension.equals(FILE_TYPE_AIF) || extension.equals(FILE_TYPE_AIFF)) {
contentType = CONTENT_TYPE_AIFF;
} else if ... other content types
That eventually checks if the current file extension is one of the supported container type and returns the content types based on the same.
The other piece on the board crucially was canPlayContentType(String contentType) which seems to be relying eventually on the supportedContentTypes for each platform as defined in the NativeMediaManager class.
Though I haven't tested the solution as proposed below primarily due to unawareness of the overview of the task that you intend to perform eventually. Yet, the closest to your current implementation and what Basic PlayBack guidelines suggests as well, was to try
Construct a Media instance out of the filename that you were providing.
Check for a MediaException if any while performing (1).
Further, the exception type MediaException.Type MEDIA_UNSUPPORTED states that
Indicates that this media type is not supported by this platform.
Drawing from the analogy with this and your current solution, you could probably make use of the this:
private static boolean isPlayable(String filename) {
try {
Media media = new Media(filename);
} catch (MediaException e) {
if (e.getType() == MediaException.Type.MEDIA_UNSUPPORTED) {
return false;
}
}
return true;
}
PS: Though I believe this could be further optimized if you actually start making use of the Media constructed(as in the above stub) right away in your piece of code instead of just dropping it.

Want to check if Java is installed and if so, which version [duplicate]

This question already has answers here:
How to get the current Java version available?
(3 answers)
Closed 8 years ago.
I want to check in C# if JRE is installed, and secondly which version and if it meets the required version for my application.
I'm currently using the following code:
RegistryKey rk = Registry.LocalMachine;
RegistryKey subKey = rk.OpenSubKey("SOFTWARE\\JavaSoft\\Java Runtime Environment");
string currentVersion = subKey.GetValue("CurrentVersion").ToString();
string neededVersion = "1.7";
if (currentVersion == neededVersion)
{
//do something
}
else
{
//do something else
}
But that only works on a computer with Java in it's Registry. Otherwise, you will get an System.NullReferenceException.
I have no idea how I should do this, could someone help me?
It is a bit difficult because I want to use two things asked earlier in one script.
There are two ways you can do this, I think - one is the way you're doing this above, and the other would be as Luiggi suggests, which would be to execute a cmd command from your C# program.
I think you're probably better off just querying the registry like you're doing, but either using try-catch blocks or checking for null, and handling failure somehow.
However, if I'm mistaken, and there are common ways the user can have Java without having a registry entry, I would go with System.Diagnostics.Process. The System.Diagnostics.ProcessStartInfo object can be used to construct all the options for the process and is passed to the Process before it is started.
try
{
ProcessStartInfo procStartInfo = new ProcessStartInfo(yourFilePath, yourArgument);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}

Java Jinput: rescan / reload controllers

I am using java jinput library to read data from joypad, and I have trouble reloading Controllers, I use this to load them:
public Controller[] findStickControllers() {
ControllerEnvironment ce =
ControllerEnvironment.getDefaultEnvironment();
Controller[] cs = ce.getControllers();
System.out.println(cs.length); //test
ArrayList<Controller> sel = new ArrayList<>();
for (Controller c: cs) {
if(c.getType() == Type.STICK) {
sel.add(c);
}
}
return sel.toArray(new Controller[]{});
}
This works fine, but if I disconnect my controller, calling this will find it again, and vice versa (connecting it after the first check will not find it at all).
I have tried to put sleep before the fist lookup, with these results:
Controllers are acctually scanned when this method is called first time (not at start of the program)
When called again, this always returns same controllers as it returned for the first time.
First call will also write warning bellow
Even when controller is connected (and works), then disconnected (it will still find it though) and reconnected, it will not work
Warning from point 3: (didn't format well in the list)
WARNING: Found unknown Windows version: Windows 8
Attempting to use default windows plug-in.
Loading: net.java.games.input.DirectAndRawInputEnvironmentPlugin
I am using Win 8, and had same problem on Win 7. I had also tried this with mouse, same results.
How can I acctually reload controllers for the 2nd, 3rd, and so on time?
I encountered the same problem. The reason is that the actual hardware scan happens only once for each DefaultControllerEnvironment object. Since the only accessible instantiation is a singleton, it never does another scan.
A simple way to force a hardware scan is to create a new object, but neither the class nor the constructor are public. You can however work around this limitation by calling the constructor via reflection.
Rescan
private static ControllerEnvironment createDefaultEnvironment() throws ReflectiveOperationException {
// Find constructor (class is package private, so we can't access it directly)
Constructor<ControllerEnvironment> constructor = (Constructor<ControllerEnvironment>)
Class.forName("net.java.games.input.DefaultControllerEnvironment").getDeclaredConstructors()[0];
// Constructor is package private, so we have to deactivate access control checks
constructor.setAccessible(true);
// Create object with default constructor
return constructor.newInstance();
}
Usage
// Be aware that creating a new environment is fairly expensive
Controller[] controllers = createDefaultEnvironment().getControllers();
Remove Windows 8 Warnings
/**
* Fix windows 8 warnings by defining a working plugin
*/
static {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
String os = System.getProperty("os.name", "").trim();
if (os.startsWith("Windows 8")) { // 8, 8.1 etc.
// disable default plugin lookup
System.setProperty("jinput.useDefaultPlugin", "false");
// set to same as windows 7 (tested for windows 8 and 8.1)
System.setProperty("net.java.games.input.plugins", "net.java.games.input.DirectAndRawInputEnvironmentPlugin");
}
return null;
}
});
}
If you use the accepted answer, you might want to consider killing the thread that was spawned by the previous environment before setting a new one because it won't be cleaned up otherwise. You can do so by calling something like:
final Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (final Thread thread : threadSet) {
final String name = thread.getClass().getName();
if (name.equals("net.java.games.input.RawInputEventQueue$QueueThread")) {
thread.interrupt();
try {
thread.join();
} catch (final InterruptedException e) {
thread.interrupt();
}
}
}
The warning is because the last time I updated that code windows 7 wasn't even out IIRC, I'll update it.
The controller reload is a feature that has been requested a number of times, but no-one deems it important enough to spend any time implementing it. If you submit a patch I'll take a look and see about committing it. Until someone finds it important enough to spend the time to write it, it's just a missing feature.
I had the same problem before.
I add the rescanning feature (for Windows back-end only) and post the patch on Java gaming forum but no ones seem interested in to integrate it.
So if you need it, apply my patch from here: http://www.java-gaming.org/topics/rescan-controllers/24782/msg/224604/view.html#msg224604

How to detect that code is running inside eclipse IDE

How to detect that code is running inside eclipse IDE
I am not aware of a generic way to get this kind of information.
One suggestion:
When you start a Java program (or a web server) inside Tomcat, simply add an argument that will indicate that this program is launched by Eclipse.
You can do that by opening the "Open Run Dialog" ("Run" menu), then select your type of application and add in the "Arguments" tab a -DrunInEclipse=true.
In your Java code, you can check the value of the property:
String inEclipseStr = System.getProperty("runInEclipse");
boolean inEclipse = "true".equalsIgnoreCase(inEclipseStr);
This way, if the program is not running inside Eclipse (or unfortunately if you forgot to set the property) the property will be null and then the boolean inEclipse will be equal to false.
Although I agree that having the code detecting a single IDE as the dev env is not an optimal solution, the following code works.
Like others proposed, using a flag at runtime is better.
public static boolean isEclipse() {
boolean isEclipse = System.getProperty("java.class.path").toLowerCase().contains("eclipse");
return isEclipse;
}
1) Create a helper method like:
public boolean isDevelopmentEnvironment() {
boolean isEclipse = true;
if (System.getenv("eclipse42") == null) {
isEclipse = false;
}
return isEclipse;
}
2) Add an environment variable to your launch configuration:
3) Usage example:
if (isDevelopmentEnvironment()) {
// Do bla_yada_bla because the IDE launched this app
}
Actually the code is not being run inside Eclipse, but in a separate Java process started by Eclipse, and there is per default nothing being done by Eclipse to make it any different than any other invocation of your program.
Is the thing you want to know, if your program is being run under a debugger? If so, you cannot say for certain. You CAN, however, inspect the arguments used to invoke your program and see if there is anything in there you do not like.
If your workspace matches some pattern like "/home/user/workspace/Project" you can use the code below:
Boolean desenv = null;
boolean isDevelopment() {
if (desenv != null) return desenv;
try {
desenv = new File(".").getCanonicalPath().contains("workspace");
}
catch (IOException e) {
e.printStackTrace();
}
return desenv;
}
A more generic and precise way, that can be used on any IDE would be loop at:
ManagementFactory.getRuntimeMXBean().getInputArguments()
looking for "-Xdebug" || (starting with) "-agentlib:jdwp=".
I came with this from #saugata comment here.
This is excellent if you want to throw a conditional exception preventing the application from simply exiting. Use a boolean like "ideWait" and add it to Eclipse watch expressions as ideWait=false, so whenever you stop at that throw, and "drop to frame" you can continue debugging happily (I mean it!)
I don't think there is any way to do this. But what I would suggest is just a command line argument such as 'debug'. Then in your main method just do
if (args.length > 0 && args[0].equalsIgnoreCase("debug")) {
// do whatever extra work you require here or set a flag for the rest of the code
}
This way you can also get your extra code to run whenever you want just by specifiying the debug parameter but under normal conditions it will never execute.
This might work if your alternative execution work flow provides a different set of dependencies:
boolean isRunningInEclipe = false;
try {
Workbench.getInstance();
isRunningInEclipe = true;
} catch (NoClassDefFoundError error) {
//not running in Eclipse that would provide the Workbench class
}
You could detect if you're inside a JAR or not, as per Can you tell on runtime if you're running java from within a jar?
Eclipse will run your app from the classes/ dir, whereas most of your end users will be running the app from a JAR.
System.out.println("Is my parent eclipse[.exe]? " +
ProcessHandle.current()
.parent()
.flatMap(parent -> parent.info().command())
.orElse("")
.matches("^.*eclipse(\\.exe)?$"));
You may try something like this:
if (ClassLoader.getSystemResource("org/eclipse/jdt/core/BindingKey.class")!=null){
System.out.println("Running within Eclipse!!!");
} else {
System.out.println("Running outside Eclipse!!!");
}

What is the best way to detect whether an application is launched by Webstart

As it was made clear in my recent question, Swing applications need to explicitly call System.exit() when they are ran using the Sun Webstart launcher (at least as of Java SE 6).
I want to restrict this hack as much as possible and I am looking for a reliable way to detect whether the application is running under Webstart. Right now I am checking that the value of the system property "webstart.version" is not null, but I couldn't find any guarantees in the documentation that this property should be set by future versions/alternative implementations.
Are there any better ways (preferably ones that do not ceate a dependency on the the webstart API?)
When your code is launched via javaws, javaws.jar is loaded and the JNLP API classes that you don't want to depend on are available. Instead of testing for a system property that is not guaranteed to exist, you could instead see if a JNLP API class exists:
private boolean isRunningJavaWebStart() {
boolean hasJNLP = false;
try {
Class.forName("javax.jnlp.ServiceManager");
hasJNLP = true;
} catch (ClassNotFoundException ex) {
hasJNLP = false;
}
return hasJNLP;
}
This also avoids needing to include javaws.jar on your class path when compiling.
Alternatively you could switch to compiling with javaws.jar and catching NoClassDefFoundError instead:
private boolean isRunningJavaWebStart() {
try {
ServiceManager.getServiceNames();
return ds != null;
} catch (NoClassDefFoundError e) {
return false;
}
}
Using ServiceManager.lookup(String) and UnavailableServiceException is trouble because both are part of the JNLP API. The ServiceManager.getServiceNames() is not documented to throw. We are specifically calling this code to check for a NoClassDefFoundError.
Use the javax.jnlp.ServiceManager to retrieve a webstart service.
If it is availabe, you are running under Webstart.
See http://download.java.net/jdk7/docs/jre/api/javaws/jnlp/index.html
As you mentioned, checking the System property as follows is probably the cleanest way:
private boolean isRunningJavaWebStart() {
return System.getProperty("javawebstart.version", null) != null;
}
In a production system I have used the above technique for years.
You can also try to check to see if there are any properties that start with "jnlpx." but none of those are really "guaranteed" to be there either as far as I know.
An alternative could be to attempt to instantiate the DownloadService us suggested by Tom:
private boolean isRunningJavaWebStart() {
try {
DownloadService ds = (DownloadService) ServiceManager.lookup("javax.jnlp.DownloadService");
return ds != null;
} catch (UnavailableServiceException e) {
return false;
}
}
Of course that does have the downside of coupling your code to that API.
I have no real experience with Java web start other than looking at it a few years back.
How about start your application with a parameter that you define than you set when the app is started via Java web start.
If you want to pass in arguments to your app, you have to add them to the start-up file (aka JNLP descriptor) using or elements.
Then check to see if these properties are set.
Again this is a suggestion I have not coded for JWS and it may not be this easy.
You can check whether the current classloader is an instance of com.sun.jnlp.JNLPClassLoader (Java plugin 1) or sun.plugin2.applet.JNLP2ClassLoader (Java plugin 2). Despite the "applet" package, an applet using JNLP with the Java plugin 2 uses another classloader, sun.plugin2.applet.Applet2ClassLoader. It works with OpenJDK too.

Categories