I developed a little Java Swing application to look up character statistics in World of Warcraft with their developer API using Netbeans in Ubuntu Gnome 14.04. Everything works as I've intended with the exception of a button that calls a method that opens a link in the default browser to the specified character's profile. On Ubuntu, the string I use in the URL renders correctly, but on Windows it does not. If I run the application (in Windows) using a batch file that specifies UTF-8 encoding for the JVM, I do not have this issue. When running it directly from the .jar file, characters such as "â" register as "â" in the URL on Windows despite my attempt at encoding all of my strings as UTF-8. How can I get the URL be properly formatted? I'm assuming there's something I'm missing. If you need to see more of the code, let me know. Thank you in advance.
ArmoryScanner_UI.java
private void openArmoryLink() {
ArmoryScanner_Backend armory = new ArmoryScanner_Backend();
String name;
String realm;
String locale;
try {
name = new String(jTextField_Name.getText().getBytes("UTF-8"));
realm = jComboBox_Realm.getSelectedItem().toString();
locale = jComboBox_Locale.getSelectedItem().toString();
if (!name.trim().isEmpty()) {
name = formatName(name);
realm = formatRealm(realm);
locale = formatLocale(locale);
armory.setPlayerInfo(name, realm, locale);
if (armory.isCharacterFound()) {
armory.setArmoryLink();
} else {
showErrorMessage("Character not found.");
jTextField_Name.setText("");
jTextField_Name.setCaretPosition(0);
jTextField_Name.requestFocus();
}
} else {
showErrorMessage("Please enter a character name.");
jTextField_Name.setText("");
jTextField_Name.setCaretPosition(0);
jTextField_Name.requestFocus();
}
} catch (UnsupportedEncodingException e) {
showErrorMessage("Error converting name to UTF-8\n"
+ e.getMessage());
}
}
private String formatName(String name) {
String result;
try {
result = new String(name.getBytes("UTF-8"), "UTF-8");
} catch (UnsupportedEncodingException e) {
showErrorMessage("Error converting name to UTF-8\n"
+ e.getMessage());
result = "";
}
return result;
}
ArmoryScanner_Backend.java
public void setArmoryLink () {
try {
String baseURL = "https://us.battle.net/wow/en/character/";
String fullURL = (baseURL + realm + "/" + name + "/simple");
System.out.println("Full URL: " + fullURL);
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().browse(new URL(fullURL).toURI());
} else {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("xdg-open " + fullURL);
} catch (IOException e) {
System.out.println("I/O exception (non-Windows system)");
}
}
} catch (UnsupportedOperationException e) {
System.out.println("Unsupported OS");
} catch (MalformedURLException e) {
System.out.println("Bad URL");
} catch (IOException e) {
System.out.println("I/O exception.");
} catch (URISyntaxException e) {
System.out.println("Bad URI syntax");
}
}
This method works fine:
private void submit() {
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
ArmoryScanner_Backend armory = new ArmoryScanner_Backend();
String name;
String realm;
String locale;
try {
name = new String(jTextField_Name.getText().getBytes("UTF-8"));
realm = jComboBox_Realm.getSelectedItem().toString();
locale = jComboBox_Locale.getSelectedItem().toString();
if (!name.trim().isEmpty()) {
name = formatName(name);
realm = formatRealm(realm);
locale = formatLocale(locale);
armory.setPlayerInfo(name, realm, locale);
if (armory.isCharacterFound()) {
setStatistics(armory);
setProgression(armory);
} else {
showErrorMessage("Character not found.");
jTextField_Name.setText("");
jTextField_Name.setCaretPosition(0);
jTextField_Name.requestFocus();
}
} else {
showErrorMessage("Please enter a character name.");
jTextField_Name.setText("");
jTextField_Name.setCaretPosition(0);
jTextField_Name.requestFocus();
}
} catch (UnsupportedEncodingException e) {
showErrorMessage("Error converting name to UTF-8\n"
+ e.getMessage());
}
this.setCursor(Cursor.getDefaultCursor());
}
Java uses Unicode on the inside, so you don't usually need to set the encoding EXCEPT when you read/write outside resources.
There you need to have it explicitly.
In your case you need to encode the elements of the URL with the class URLEncoder.
Have a look at the documentation.
Related
I am trying to develop Java web Tesseract OCR application. Following code works perfectly :
public class App {
public String getImgText(String imageLocation) {
ITesseract instance = new Tesseract();
instance.setDatapath(Thread.currentThread().getContextClassLoader().getResource("tessdata").getPath());
System.out.println("Thread.currentThread().getContextClassLoader().getResource(\"tessdata\").getPath() : "+Thread.currentThread().getContextClassLoader().getResource("tessdata").getPath());
instance.setLanguage("eng");
try {
String imgText = instance.doOCR(new File(imageLocation));
return imgText;
} catch (TesseractException e) {
e.getMessage();
return "Error while reading image";
}
}
public static void main(String[] args) {
App app = new App();
System.out.println(app.getImgText("/home/user/Desktop/1.png"));
}
}
But when I trying to use the above code in my Java web(JSF) application after the line
ITesseract instance = new Tesseract();
nothing is printed out. Below is the code of my web application :
public String uploadImage(FileUploadEvent event) {
System.out.println("webcore bean");
//get uploaded file from the event
UploadedFile uploadedFile = (UploadedFile) event.getFile();
//create an InputStream from the uploaded file
InputStream inputStr = null;
try {
inputStr = uploadedFile.getInputstream();
} catch (IOException e) {
//log error
}
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
String directory = externalContext.getInitParameter("uploadDirectory");
String filename = FilenameUtils.getName(uploadedFile.getFileName());
File destFile = new File(directory, "static" + getFileExtension(filename));
//use org.apache.commons.io.FileUtils to copy the File
try {
FileUtils.copyInputStreamToFile(inputStr, destFile);
} catch (IOException e) {
//log error
}
System.out.println("getImageText(directory) : " + getImageText(directory));
FacesMessage msg = new FacesMessage(event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
return null;
}
private String getImageText(String imageLocation) {
try {
System.out.println("Before ");
ITesseract instance = new Tesseract1();
System.out.println("After ");
//instance.setDatapath("/usr/share/tesseract-ocr/4.00/tessdata");
instance.setDatapath(Thread.currentThread().getContextClassLoader().getResource("tessdata").getPath());
instance.setLanguage("eng");
try {
String imgText = instance.doOCR(new File(imageLocation));
return imgText;
} catch (TesseractException e) {
e.getMessage();
return "Error while reading image";
}
} catch (Exception e) {
System.out.println("Before returning null");
e.printStackTrace();
return null;
}
}
The log "Before" is being printed but the log "After" is not being printed. I am using following technologies :
a) Ubuntu 18.04 64 bit OS
b) Netbeans
c) Maven
d) Glassfish 4.1
I am executing the below code to pull the .gz file from a URL to a local directory.For small files it goes through fine but for large files it downloads only part of it but does not fail. I get to know the error only when I try to UNZIP it. Can someone throw any light on this on what could be the reason.
public boolean downloadFilemethod(String filePath, String url, String
decompressFilePath) {
if (StringUtils.isNotBlank(filePath) && StringUtils.isNotBlank(url)) {
try {
FileUtils.copyURLToFile(new URL(url), new File(SRC_BASE_DIR + filePath),
TIMEOUT_IN_MILLIS, TIMEOUT_IN_MILLIS);
ingestmethod(filePath,decompressFilePath);
downloadSuccess = true;
}
catch (MalformedURLException e)
{ LOG.warn("some message"); }
catch (IOException e)
{ LOG.warn("some message);
}
}
return downloadSuccess
}
I am working on an application that retrieves files from different URL's.
There is a TreeSet that contains the target to download. This is processed in a loop with each item being called with an ExecutorService. Here's some code:
private void retrieveDataFiles() {
if (this.urlsToRetrieve.size() > 0) {
System.out.println("Target URLs to retrieve: " + this.urlsToRetrieve.size());
ExecutorService executorProcessUrls = Executors.newFixedThreadPool(this.urlsToRetrieve.size());//could use fixed pool based on size of urls to retrieve
for (Entry target : this.urlsToRetrieve.entrySet()) {
final String fileName = (String) target.getKey();
final String url = (String) target.getValue();
String localFile = localDirectory + File.separator + fileName;
System.out.println(localFile);
executorProcessUrls.submit(new WikiDumpRetriever(url, localFile));
dumpFiles.add(localFile);
//TODO: figure out why only 2 files download
}
executorProcessUrls.shutdown();
try {
executorProcessUrls.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException ex) {
System.out.println("retrieveDataFiles InterruptedException: " + ex.getMessage());
}
} else {
System.out.println("No target URL's were retrieved");
}
}
Then the WikiDumpRetriever:
private static class WikiDumpRetriever implements Runnable {
private String wikiUrl;
private String downloadTo;
public WikiDumpRetriever(String targetUrl, String localDirectory) {
this.downloadTo = localDirectory;
this.wikiUrl = targetUrl;
}
public void downloadFile() throws FileNotFoundException, IOException, URISyntaxException {
HTTPCommunicationGet httpGet = new HTTPCommunicationGet(wikiUrl, "");
httpGet.downloadFiles(downloadTo);
}
#Override
public void run() {
try {
downloadFile();
} catch (FileNotFoundException ex) {
System.out.println("WDR: FileNotFound " + ex.getMessage());
} catch (IOException ex) {
System.out.println("WDR: IOException " + ex.getMessage());
} catch (URISyntaxException ex) {
System.out.println("WDR: URISyntaxException " + ex.getMessage());
}
}
}
As you can see this is an inner class. The TreeSet contains:
Key : Value
enwiki-latest-pages-articles.xml.bz2 : http://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2
elwiki-latest-pages-articles.xml.bz2 : http://dumps.wikimedia.org/enwiki/latest/elwiki-latest-pages-articles.xml.bz2
zhwiki-latest-pages-articles.xml.bz2 : http://dumps.wikimedia.org/enwiki/latest/zhwiki-latest-pages-articles.xml.bz2
hewiki-latest-pages-articles.xml.bz2 : http://dumps.wikimedia.org/enwiki/latest/hewiki-latest-pages-articles.xml.bz2
The problem is that this process downloads 2 of the four files. I know that all four are available and I know that they can be downloaded. However, only 2 of them process at any time.
Can anyone shed any light on this for me please - what am I missing or what am I getting wrong?
Thanks
nathj07
Thanks to ppeterka - it was a limit from the source. So, to overcome this I set the fixed thread pool size to 2. This means that only 2 files are downloaded simultaneously.
The answer then was to find the vendor imposed limit and set the thread pool:
ExecutorService executorProcessUrls = Executors.newFixedThreadPool(2);
I wanted to accept an answer but couldn't seem to do it with the comments. Sorry if this was the wrong way to do it.
Thanks for all the pointers - the 'group think' really helped solve this for me.
I used the following code to run an exe I load through my code.
private static String filelocation = "";
.
load_exe.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
JFileChooser file_Choose = new JFileChooser();
file_Choose.showOpenDialog(frame);
JavaSamp.filelocation = file_Choose.getCurrentDirectory()
.toString()
+ "\\" + file_Choose.getSelectedFile().getName();
System.out.println("FileLocation" + JavaSamp.filelocation);
} catch (Exception expobj) {
// TODO Auto-generated catch block
}
Runtime rt = Runtime.getRuntime();
try {
System.out.println("File Run Location" + JavaSamp.filelocation);
proc = rt.exec(JavaSamp.filelocation);
} catch (IOException e4) {
e4.printStackTrace();
} catch (Exception e2) {
}
}
});
My problem is, the above execution of the JavaSamp.filelocation, should have to done many times. First time only I load the exe. Next time I wont. I need to store the exe in a string to run for the successive times.
Any suggestion pls
If you want remember the used file just initialize the filelocation with null and test for it. BTW: Storing it as File makes more sense and your way of constructing the absolute path is a bit intricate - compared to just calling getAbsolutePath()
private static File filelocation = null;
private static void test() {
load_exe.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Check if file-name to execute has already been set
if (filelocation != null) {
try {
JFileChooser file_Choose = new JFileChooser();
file_Choose.showOpenDialog(frame);
JavaSamp.filelocation = file_Choose.getSelectedFile();
System.out.println("FileLocation"
+ JavaSamp.filelocation.getAbsolutePath());
} catch (Exception expobj) {
}
}
Runtime rt = Runtime.getRuntime();
try {
System.out.println("File Run Location"
+ JavaSamp.filelocation.getAbsolutePath());
Process proc = rt.exec(JavaSamp.filelocation
.getAbsolutePath());
} catch (IOException e4) {
e4.printStackTrace();
}
}
};
}
I'm trying to package up resources into a jar, but I'm having trouble getting Flying Saucer to find the css on the classpath - I can't construct a URL easily to be able to resolve this seamlessly.
Does Flying saucer have a way of specifying resource packages on the classpath to resolve items and images?
Note: I'm running this in a webstart application that does not have file system writing permissions, so jar expansion is not really an option.
You should implement a UserAgentCallback that you feed to the XHTMLPanel, something like this:
private static class UAC extends NaiveUserAgent {
#Override
public String resolveURI(String uri) {
return uri;
}
#Override
protected InputStream resolveAndOpenStream(String uri) {
java.io.InputStream is = null;
URL url = UAC.class.getResource(uri);
if (url == null) {
XRLog.load("Didn't find resource [" + uri + "].");
return null;
}
try {
is = url.openStream();
}
catch (java.net.MalformedURLException e) {
XRLog.exception("bad URL given: " + uri, e);
}
catch (java.io.FileNotFoundException e) {
XRLog.exception("item at URI " + uri + " not found");
}
catch (java.io.IOException e) {
XRLog.exception("IO problem for " + uri, e);
}
return is;
}
}
XHTMLPanel panel = new XHTMLPanel(new UAC());
My solution is
private static class UserAgentCallback extends ITextUserAgent {
public UserAgentCallback(ITextOutputDevice outputDevice, SharedContext sharedContext) {
super(outputDevice);
setSharedContext(sharedContext);
}
#Override
public String resolveURI(String uri) {
return uri;
}
#Override
protected InputStream resolveAndOpenStream(String uri) {
java.io.InputStream is = null;
URL url = null;
try {
url = new ClassPathResource("/META-INF/pdfTemplates/" + uri).getURL();
} catch (IOException e) {
XRLog.exception("bad URL given: " + uri, e);
}
if (url == null) {
XRLog.load("Didn't find resource [" + uri + "].");
return null;
}
try {
is = url.openStream();
} catch (java.net.MalformedURLException e) {
XRLog.exception("bad URL given: " + uri, e);
} catch (java.io.FileNotFoundException e) {
XRLog.exception("item at URI " + uri + " not found");
} catch (java.io.IOException e) {
XRLog.exception("IO problem for " + uri, e);
}
return is;
}
}
and invocation:
renderer.getSharedContext()
.setUserAgentCallback(new UserAgentCallback(renderer.getOutputDevice(), renderer.getSharedContext()));
It would seem that flying saucer does not have a way of specifying resources on the classpath, so I work around by making a classpath: protocol url handler at the linked question
Post Implementation Findings
It would seem that the some of the premises of this question are invalid. After writing my own classpath URL loader, I found that you need to request <all-permissions/> in the jnlp to be able to use URL.setURLStreamHandlerFactory(). In fact, you need to request all permissions to do just about anything fancy (even though you're only modifying your own sand-box). See the full list here.
In short, this means that I am able to extract files to the operating system. But it's nice having a classpath loader now...