I have encountered this error:
java.lang.UnsupportedOperationException: Desktop API is not supported on the current platform
I would open a file from my java application. I use this method:
Desktop.getDesktop().open(new File(report.html"));
How can i solve this problem?
Basically, the problem is that Java Desktop integration doesn't work well on Linux.
It was designed to work good with Windows; something works on other systems, but nobody really cared to add proper support for those. Even if you install the required 'gnome libraries', the results will be poor.
I've faced the very same problem a while ago, and came up with the class below.
The goal is achieved by using system-specific commands:
KDE: kde-open
GNOME: gnome-open
Any X-server system: xdg-open
MAC: open
Windows: explorer
If none of those works, it tries the implementation provided by Java Desktop.
Because this one usually fails, it's tried as the last resort.
DesktopApi class
This class provides static methods open, browse and edit.
It is tested to work on Linux (Kde and Gnome), Windows and Mac.
If you use it, please give me credit.
package net.mightypork.rpack.utils;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
public class DesktopApi {
public static boolean browse(URI uri) {
if (openSystemSpecific(uri.toString())) return true;
if (browseDESKTOP(uri)) return true;
return false;
}
public static boolean open(File file) {
if (openSystemSpecific(file.getPath())) return true;
if (openDESKTOP(file)) return true;
return false;
}
public static boolean edit(File file) {
// you can try something like
// runCommand("gimp", "%s", file.getPath())
// based on user preferences.
if (openSystemSpecific(file.getPath())) return true;
if (editDESKTOP(file)) return true;
return false;
}
private static boolean openSystemSpecific(String what) {
EnumOS os = getOs();
if (os.isLinux()) {
if (runCommand("kde-open", "%s", what)) return true;
if (runCommand("gnome-open", "%s", what)) return true;
if (runCommand("xdg-open", "%s", what)) return true;
}
if (os.isMac()) {
if (runCommand("open", "%s", what)) return true;
}
if (os.isWindows()) {
if (runCommand("explorer", "%s", what)) return true;
}
return false;
}
private static boolean browseDESKTOP(URI uri) {
logOut("Trying to use Desktop.getDesktop().browse() with " + uri.toString());
try {
if (!Desktop.isDesktopSupported()) {
logErr("Platform is not supported.");
return false;
}
if (!Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
logErr("BROWSE is not supported.");
return false;
}
Desktop.getDesktop().browse(uri);
return true;
} catch (Throwable t) {
logErr("Error using desktop browse.", t);
return false;
}
}
private static boolean openDESKTOP(File file) {
logOut("Trying to use Desktop.getDesktop().open() with " + file.toString());
try {
if (!Desktop.isDesktopSupported()) {
logErr("Platform is not supported.");
return false;
}
if (!Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
logErr("OPEN is not supported.");
return false;
}
Desktop.getDesktop().open(file);
return true;
} catch (Throwable t) {
logErr("Error using desktop open.", t);
return false;
}
}
private static boolean editDESKTOP(File file) {
logOut("Trying to use Desktop.getDesktop().edit() with " + file);
try {
if (!Desktop.isDesktopSupported()) {
logErr("Platform is not supported.");
return false;
}
if (!Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) {
logErr("EDIT is not supported.");
return false;
}
Desktop.getDesktop().edit(file);
return true;
} catch (Throwable t) {
logErr("Error using desktop edit.", t);
return false;
}
}
private static boolean runCommand(String command, String args, String file) {
logOut("Trying to exec:\n cmd = " + command + "\n args = " + args + "\n %s = " + file);
String[] parts = prepareCommand(command, args, file);
try {
Process p = Runtime.getRuntime().exec(parts);
if (p == null) return false;
try {
int retval = p.exitValue();
if (retval == 0) {
logErr("Process ended immediately.");
return false;
} else {
logErr("Process crashed.");
return false;
}
} catch (IllegalThreadStateException itse) {
logErr("Process is running.");
return true;
}
} catch (IOException e) {
logErr("Error running command.", e);
return false;
}
}
private static String[] prepareCommand(String command, String args, String file) {
List<String> parts = new ArrayList<String>();
parts.add(command);
if (args != null) {
for (String s : args.split(" ")) {
s = String.format(s, file); // put in the filename thing
parts.add(s.trim());
}
}
return parts.toArray(new String[parts.size()]);
}
private static void logErr(String msg, Throwable t) {
System.err.println(msg);
t.printStackTrace();
}
private static void logErr(String msg) {
System.err.println(msg);
}
private static void logOut(String msg) {
System.out.println(msg);
}
public static enum EnumOS {
linux, macos, solaris, unknown, windows;
public boolean isLinux() {
return this == linux || this == solaris;
}
public boolean isMac() {
return this == macos;
}
public boolean isWindows() {
return this == windows;
}
}
public static EnumOS getOs() {
String s = System.getProperty("os.name").toLowerCase();
if (s.contains("win")) {
return EnumOS.windows;
}
if (s.contains("mac")) {
return EnumOS.macos;
}
if (s.contains("solaris")) {
return EnumOS.solaris;
}
if (s.contains("sunos")) {
return EnumOS.solaris;
}
if (s.contains("linux")) {
return EnumOS.linux;
}
if (s.contains("unix")) {
return EnumOS.linux;
} else {
return EnumOS.unknown;
}
}
}
I am using Ubuntu 12.04 LTS 64-bit with Oracle jdk1.6.0_45 and was having the same problem.
I’m running gnome-classic as the desktop instead of Unity. This is what worked for me:
sudo apt-get install libgnome2-0
After installing this package I restarted my Java Swing app and Desktop.getDesktop().open(new File("myfile")); worked just fine.
The Desktop class is not supported on all systems.
From the Java Swing tutorial How to Integrate with the Desktop Class:
Use the isDesktopSupported() method to determine whether the Desktop API is available. On the Solaris Operating System and the Linux platform, this API is dependent on Gnome libraries. If those libraries are unavailable, this method will return false. After determining that the Desktop API is supported, that is, the isDesktopSupported() returns true, the application can retrieve a Desktop instance using the static method getDesktop().
In any case, it would be best to provide an alternative way to open a file if there is no support for Desktop.
Support varies between implementations on the various JDKs. I encountered the "UnsupportedOperationException" using OpenJDK 1.7.0. Switching to the Oracle JDK 1.7 worked.
Where practical, you may be able to switch JDKs or suggest that your users switch JDKs to enable a certain feature.
Related
I made a DRM media player app in Xamarin which drops course.licns and pass.licns files in internal memory in app directory for reading correct key.
It's working fine in Android 10 but it's not working in above versions like Android 11 and 12 when I put course name and key then app added both files but can't read it again when I want to play a video. The same thing is working fine on lower versions.
My code:
using System;
using System.Text;
using System.IO;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Android.OS;
namespace MediaElement
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Add : ContentPage
{
public Add()
{
InitializeComponent();
}
async void Appears(object sender, EventArgs e)
{
try
{
this.FindByName<Entry>("ID").Text =Helper. GetIMEI();
}
catch (Exception e2)
{
await DisplayAlert("Error!", e2.Message, "Ok");
}
}
public static string Pass()
{
return Path.Combine((string)System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "pass.licns");
//return Path.Combine((string)System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "pass.licns");
}
public static string Course()
{
//return Path.Combine((string)System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "course.licns");
return Path.Combine((string)System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "course.licns");
}
void Register(object sender, EventArgs e)
{
try
{
string key = this.FindByName<Entry>("Key").Text.Trim();
string Name = this.FindByName<Entry>("Name").Text.Trim();
if (key== string.Empty || Name == string.Empty) { throw new Exception("Key or Name is empty"); }
if (!IsBase(key)) { throw new Exception("Invalid key!"); }
if (!IsValidID(key)) { throw new Exception("This key is not designed for your ID."); }
if (File.Exists(Pass()) && File.Exists(Course()))
{
if (File.ReadAllText(Pass()).Contains(key) || File.ReadAllText(Course()).Contains(Name)){ throw new Exception("Key or Course Already exists."); }
}
File.AppendAllText(Pass(), key+",");
File.AppendAllText(Course(), Name + ",");
DisplayAlert("Success", "License added successfully.", "Ok");
}
catch (Exception e2)
{
DisplayAlert("Error", e2.Message, "Ok");
}
}
bool IsBase(string base64)
{
try
{
if (base64 == Convert.ToBase64String(Convert.FromBase64String(base64))) { return true; }
}
catch (Exception)
{
}
return false;
}
public static bool IsValidID(string key)
{
return Encoding.ASCII.GetString(MainPage.Decrypt(Convert.FromBase64String(key),Helper. IDkey)).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)[0].ToString() == Helper. GetIMEI();
}
}
}
Note:
I don't want to use All file access permissions due to so many restrictions in Google Play Store and my App is only accessing a particular file. Is there a proper way for upper versions?
I am an Android beginner and I was working on my first project, which is a calculator for fractions. The app had an error which I was unable to fix and so I got frustrated and I quit (I didn't delete or do anything with the files tho). Around 3-4 days later (today) I suddenly got the solution. I opened up Android Studio, just to see that my mainactivity's icon is changed and it has become a kind of folder, which contains the file AppErrorResult. Here's a screenshot:
Here's AppErrorResult:
package com.android.server.am;
final class AppErrorResult {
public void set(int res) {
synchronized (this) {
mHasResult = true;
mResult = res;
notifyAll();
}
}
public int get() {
synchronized (this) {
while (!mHasResult) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mResult;
}
boolean mHasResult = false;
int mResult;
}
I have a spring boot application. These are the classes:
RunBatchFile.java
public class RunBatchFile {
private Boolean isSuccessful;
private String content;
public void RunningBatchCommand() {
String filePath = "C:/Users/attsuap1/Desktop/test.bat";
try {
Process p = Runtime.getRuntime().exec(filePath);
int exitVal = p.waitFor();
if (exitVal == 0)
{
isSuccessful = true;
}
else {
isSuccessful = false;
}
System.out.println(isSuccessful);
} catch (Exception e) {
e.printStackTrace();
}
}
public RunBatchFile(Boolean isSuccessful) {
this.isSuccessful = isSuccessful;
this.content = content;
}
public RunBatchFile(String format) {
// TODO Auto-generated constructor stub
}
public Boolean getisSuccessful() {
return isSuccessful;
}
public String getContent() {
return content;
}
}
BatchFileController
#RestController
public class BatchFileController {
private static final String template = "Sum, %s!";
private static boolean isSuccessful;
#RequestMapping("/runbatchfile")
#ResponseBody
public RunBatchFile runbatchFile(#RequestParam(value = "isSuccessful") Boolean isSuccessful) {
return new RunBatchFile(String.format(template, isSuccessful));
}
}
The runBatchFile.java class executes a batch file and will show output as either true or false depending on whether the batch file has executed its commands correctly or not. I want to display that output on a web browser therefore i have created the BatchFileController.java class.
I get the error:
Required Boolean parameter 'isSuccessful' is not present
How do i edit my codes to make this work? Which means, either {true} or {false} is shown on the web browser when i run localhost:8080/runbatchfile?
I'm not quite sure what you are doing. The issue you are having with your controller is that you have defined your method to require a boolean parameter. Given your scenario, that would not make sense, as you would not tell the endpoint the result of the script running; the endpoint tells you that. Your method return type should be boolean instead.
Generally this would be the way to go about this if it is a short running script. I tested with a simple ping command and things worked out. Pointing to an invalid IP failed.
If the script takes a lot of time, you're going to want to go async where you submit a job, and you can check back with a different method to see what the status is.
I would have a class to run your batch file:
public class RunBatchFile {
public boolean runBatch() {
String filePath = "C:/Users/attsuap1/Desktop/test.bat";
try {
Process p = Runtime.getRuntime().exec(filePath);
int exitVal = p.waitFor();
return exitVal == 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
And then in your controller:
#RequestMapping("/runbatchfile")
public boolean runbatchFile() {
RunBatchFile rbf = new RunBatchFile();
return rbf.runBatch();
}
If you want to wrap your results so your response isn't just a true/false string. Note that the return type of the method has changed to a simple POJO:
Class
public class RunBatchFile {
public ResultWrapper runBatch() {
String filePath = "C:/Users/attsuap1/Desktop/test.bat";
try {
Process p = Runtime.getRuntime().exec(filePath);
int exitVal = p.waitFor();
return new ResultWrapper(exitVal == 0);
} catch (Exception e) {
e.printStackTrace();
return new ResultWrapper(false);
}
}
}
Wrapper Class
public class ResultWrapper {
private boolean result;
public ResultWrapper(boolean result) {
this.result = result;
}
public boolean getResult() {
return result;
}
}
Controller Method
#RequestMapping("/runbatchfile")
public ResultWrapper runbatchFile() {
RunBatchFile rbf = new RunBatchFile();
return rbf.runBatch();
}
I've created a simple shell script which basically just starts an ".jar" file.
this script contains the following
now=$(date +"%s")
sudo java -jar /home/pi/Desktop/test.jar > /home/pi/Desktop/output_$now.txt
I added the script to the crontask with
#reboot sudo bash /home/pi/Desktop/testmygps.sh
My application is going to be a "GPS controller" which is used for dropping baits for foxes (immunization against rabies).
My application consists of 3 threads, one for updating the connected LCD Display, one for updating the GPS position and speed and one for dropping the baits.
I use serial communication for the GPS Modul (and then extract the needed data) and the pi4j library (v1.1) to communicate with the GPIOs.
When I start the jar from the terminal everything works as expected (so far I just calculate the distances between the drops and save every drop coordinate, and at the LCD shows the current speed and the calculated delay between the drops).
But when I reboot my pi with 'sudo reboot' my jar starts, then a few 'speed updates' are made and then somehow the connection to the connection to the GPS module gets lost and only the LCD continues to work.
Anyone an idea what could be the cause of my problem?
PS.
This is the GPSController class of my project
package baitcontrol.v2;
import java.util.Date;
import java.util.logging.Logger;
import com.pi4j.wiringpi.Serial;
import exceptions.NMEAparseException;
import utils.Parser;
import utils.Utils;
public class GPSController implements Runnable {
private static final Logger LOGGER =
Logger.getLogger(GPSController.class.getName());
private int serialPort;
private static boolean continueLoop = true;
private static GPSController instance;
private GPGGAEvent lastGPGGAUpdateEvent;
private GPVTGEvent lastGPVTGUpdateEvent;
private GPSController() {
LOGGER.info("GPSController init");
this.serialPort = Serial.serialOpen("/dev/serial0", 9600);
LOGGER.info("GPSController initialised");
if (this.serialPort == -1) {
LOGGER.severe("Serial Port Failed");
System.out.println("Serial Port Failed");
}
}
public static GPSController getInstance() {
if (instance == null) {
instance = new GPSController();
}
return instance;
}
#Override
public void run() {
LOGGER.info("GPSController started");
String nmea = "";
while (continueLoop) {
if (Serial.serialDataAvail(serialPort) > 0) {
byte[] rawData = Serial.serialGetAvailableBytes(serialPort);
for (byte dataByte : rawData) {
char character = (char) dataByte;
if (character == '\n') {
LOGGER.fine("new nmealine " +nmea);
if(nmea.contains("GPGGA")){
LOGGER.fine("new GPGGA line");
try {
lastGPGGAUpdateEvent = Parser.parseGPGGAToGPSEvent(nmea);
} catch (NMEAparseException e) {
LOGGER.warning(e.getMessage());
System.out.println(e.getMessage());
Utils.addToTxt("error_" + Utils.dateToString(Main.startTime), e.getMessage());
}
}
if(nmea.contains("GPVTG")){
LOGGER.fine("new GPGGA line");
try {
lastGPVTGUpdateEvent = Parser.parseGPVTGToGPSEvent(nmea);
} catch (NMEAparseException e) {
LOGGER.warning(e.getMessage());
System.out.println(e.getMessage());
Utils.addToTxt("error_" + Utils.dateToString(Main.startTime), e.getMessage());
}
}
nmea = "";
}else{
nmea+=Character.toString(character);
}
}
} else {
LOGGER.finest("data empty");
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
LOGGER.finest(e.getMessage());
System.out.println(e.getMessage());
Utils.addToTxt("error_" + Utils.dateToString(Main.startTime), e.getMessage());
}
}
}
public GPGGAEvent getLastGPGGAUpdateEvent() {
return lastGPGGAUpdateEvent;
}
public GPVTGEvent getLastGPVTGUpdateEvent() {
return lastGPVTGUpdateEvent;
}
public boolean positionHasAlreadyBeenUpdated(){
return lastGPGGAUpdateEvent!=null;
}
public boolean speedHasAlreadyBeenUpdated(){
return lastGPVTGUpdateEvent!=null;
}
}
Iam working in a desktop application for windows version using java. In my application there is a requirement to search all .php
i use recursive methods;
and REGEX
my code :
import java.io.File;
public class Copier {
public static void find(String source,String rep)
{
File src=new File(rep);
if(src.exists() && src.isDirectory())
{
String[] tab=src.list();
for(String s:tab)
{
File srcc=new File(rep+"\\"+s);
if(srcc.isFile())
{
if(srcc.getName().matches(".*"+source+"$"))
System.out.println(s);
}
else
find(source,srcc.getAbsolutePath());
}
}
}
public static void main(String[] args)
{
find(".php","C:\\");
}
}
But i have this exception :
Exception in thread "main" java.lang.NullPointerException
at Copier.find(Copier.java:11)
at Copier.find(Copier.java:21)
at Copier.main(Copier.java:28)
src.list() returns null. It probably happens because you (current user) does not have access rights to the directory. I guess it is about C:\ (the root directory of disk C). This often happens especially on Windows 7.
First try to debug your code using directory where you have access rights. Then fix your code to care about nulls. Then try to run your program as an administrator.
Change main like below, for debugging purpose.
public static void main(String[] args)
{
try {
find(".php","C:\\");
} catch (Exception e) {
e.printStackTrace();
}
}
And add a null check in
if (src != null && src.exists() && src.isDirectory())
Edit:
Below works fine for me, (I am using windows 7).
import java.io.File;
public class Copier {
public static void find(String source,String rep) {
File src = new File(rep);
if (src!= null && src.exists() && src.isDirectory()) {
String[] tab = src.list();
if (tab != null) {
for(String s : tab) {
File srcc = new File(rep+"\\"+s);
if (srcc.isFile()) {
if (srcc.getName().matches(".*"+source+"$")) {
System.out.println(s);
}
} else {
find(source,srcc.getAbsolutePath());
}
}
} else {
//System.out.println(" list is null");
}
}
}
public static void main(String[] args) {
try {
find(".java", "C:\\");
} catch (Exception e) {
e.printStackTrace();
}
}
}