jar file load html pages in JEditorPane - java

I'm trying to load html pages stored inside the jar file into a help JEditorPane. So far it works when I run it in eclipse but when i make a runnable jar it wont work, except if i put the map res/pages/... in the same map with the jar file
class HelpButtonHandler implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
infodex = new JEditorPane();
helpDialog = new JDialog();
URL url1 = null;
try {
url1 = (new java.io.File("res/pages/help.html")).toURI().toURL();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
infodex.setPage(url1);
} catch (IOException e) {
e.printStackTrace();
}
helpDialog.getContentPane().add(new JScrollPane(infodex));
helpDialog.setBounds(400,200,700,600);
helpDialog.show();
infodex.setEditable(false);
Hyperactive hyper = new Hyperactive();
infodex.addHyperlinkListener(hyper);
}
}

A file packaged inside a .jar is not a file on the file system. You cannot access it with the File class.
A file inside a .jar is called an application resource. You access it using the Class.getResource method:
url1 = HelpButtonHandler.class.getResource("/res/pages/help.html");
It is up to you to make sure the files are properly packaged in your .jar. If url1 is null, check the structure of your .jar file.

When you put resources in a jar, you cannot access them using File. You need to access them as a resource through the (more precisely: a) classloader. For example:
HelpButtonHandler.class.getResource("/res/pages/help.html");
Make sure you put the resource in the right place: if you leave out the first slash ('/'), the classloader will try to locate it relative to your class (which is usually not what you want).

use gerResource() method...
url = getClass().getClassLoader().getResource("res/pages/help.html");
check this link
http://oakgreen.blogspot.com/2011/12/java-getclassgetclassloadergetresourcem.html

Related

Files.copy returns empty file when jar is exported

The file downloads properly in eclipse however when i export the jar it always downloads a blank exe. Can anyone help?
public static void downloadAndRunFile(final URL from, final File to) throws Exception {
try (final InputStream in = from.openStream()) {
Files.copy(in, to.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
Desktop.getDesktop().open(to);
}
Actual code being ran
String bub = "https://a.coka.la/bnH6Vg.exe";
try {
Pandora.downloadAndRunFile(
new URL(bub),
File.createTempFile("feelthevluci", ".exe"));
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
The URL in your code seems to return a 404.
I changed it to something that I know works and is safe, and that works both in the IDE and in a jar file.
Check the URL via curl, browser, or other tool to make sure it is working.

Reading images from external JAR

I have a simple plugin system, that loads external JAR plugins into main application. I am using Mountainblade Modular to do so. Not sure how they do it "under the hood" but probably it's something standard.
This works fine, I instantiate classes from external jar and it all works. Except that some plugins come with icons/images. I am a bit unsure on how do I load/refer to images from that external JAR (with code inside that external JAR, as it is ran in context of the main JAR, kind of)
How should I approach this?
This issue is not as straightforward as it seems to be.
When you load classes from external jar, they are "loaded" into JVM. By "loading" into JVM I mean that JVM is responsible for their storage in memory. Usually it is done like this:
ClassLoader myClassLoader = new MyClassLoader(jarFileContent);
Class myExtClass = myClassLoader.loadClass(myClassName);
Resources from classpath jars can be accessed easily with
InputStream resourceStream = myClass.getResourceAsStream("/myFile.txt");
You can do that, because these jars are in classpath, I mean their location is known. These files are not stored in memory. When resource is accessed, JVM can search for it in classpath jars (for example on file system).
But for external jars it is completely different: jar comes from nowhere, is once processed and forgotten. JVM does not load resources from it in memory. In order to access these files, you have to manually organize their storage. I've done this once so I can share the code. It will help you to understand the basic idea (but probably won't help you with your specific library).
// Method from custom UrlClassLoader class.
// jarContent here is byte array of loaded jar file.
// important notes:
// resources can be accesed only with this custom class loader
// resource content is provided with the help of custom URLStreamHandler
#Override
protected URL findResource(String name) {
JarInputStream jarInputStream;
try {
jarInputStream = new JarInputStream(new ByteArrayInputStream(jarContent));
JarEntry jarEntry;
while (true) {
jarEntry = jarInputStream.getNextJarEntry();
if (jarEntry == null) {
break;
}
if (name.equals(jarEntry.getName())) {
final byte[] bytes = IOUtils.toByteArray(jarInputStream);
return new URL(null, "in-memory-bytes", new URLStreamHandler() {
#Override
protected URLConnection openConnection(URL u) throws IOException {
return new URLConnection(u) {
#Override
public void connect() throws IOException {
// nothing to do here
}
#Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(bytes);
}
};
}
});
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

Creating a properties file in Java and eclipse

I want to create a config.properties file, in which I want to store all the key and values instead of hard coding them in the Java code.
However, I do not know how to create a properties file in eclipse.
I researched and found help on how to read a properties file.
I need help with how to create it.
Here are my specific questions:
Can a config.properties file be created in eclipse, and data be
typed directly into it as though the config.properties is similar to
text editor?
If it can be directly created, the can you please let me know the
steps to create this properties file?
I am assuming that properties file can be created just like how java
project, java class etc are created (by right clicking at package or
project level). Is this correct assumption?
Or creating a properties file and adding data to it needs to be done
by java coding?
I will greatly appreciate any help.
Create a new file from file menu Or press Ctrl+N
In place of file name write config.properties then click finish
Then you can add properties your property file like this
dbpassword=password
database=localhost
dbuser=user
Example of loading properties
public class App {
public static void main(String[] args) {
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream("config.properties");
// load a properties file
prop.load(input);
// get the property value and print it out
System.out.println(prop.getProperty("database"));
System.out.println(prop.getProperty("dbuser"));
System.out.println(prop.getProperty("dbpassword"));
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

DownloadLink with an option to choose the directory where the file should be saved apache wicket

this is my download link I did from the wicket example site. I would like to alter it by letting the user choose the directory the file should be saved. Any way to implement it? Thanks in advance
add(new DownloadLink("generate_report", new AbstractReadOnlyModel<File>()
{
private static final long serialVersionUID = 1L;
#Override
public File getObject()
{
File tempFile;
try
{
tempFile = File.createTempFile("wicket-examples-download-link--", ".tmp");
InputStream data = new ByteArrayInputStream("some data".getBytes());
Files.writeTo(tempFile, data);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
return tempFile;
}
}).setCacheDuration(Duration.NONE).setDeleteAfterDownload(true));
If you have preset paths then the user can choose which one they want to use by using the include_path function; however, the user will not be able to create their own directory/path.
EDIT: Couldn't put code in that comment lol but here is where I was going at.
$path1=set_include_path('file\whateveryouwant');
Then you can use multiple paths and let the user choose from the paths by calling the $path1 (wich would be the extension for the path you want them to use).
More info: http://php.net/manual/en/function.get-include-path.php

How do I load resources when using a classloader?

I'm using JarFile and JarURLConnection to load files out of a jar file. I'm then taking the classes, and loading them via BCEL (ByteCode Engineering Library, apache library). I cant just directly use a class loader because im modifying some classes slightly with the BCEL. I need to load the classes by their bytes into my bcel loader. However, one of the classes I'm loading references a resource. This resource is inside of the jar, so I can get the file (When iterating over the entries in the JarFile, I ignore the regular files, and take the class files for loading later). But just having the file won't do me any good, as the class loads it as a resource. Is there any way I can take that resource from the jar (well I can take it and load it into a byte[], the next part is the issue) and dynamically add it as a resource for my program, so that the classes that I load wont be missing their resources?
Got a lot of stuff here, if anythings confusing, ask in comments, I might've said something wrong, or missed something altogether :) Thanks
I'll show a little of my class loader here (extends ClassLoader):
#Override
public URL getResource(String name) {
System.out.println("LOADING RESOURCE: " + name);
try {
return new URL(null, name, new Handler(files));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
Now, it is printing out "LOADING RESOURCE: filename", but its then giving me a MalformedURLException (I have no protocol atm, just a file path, that's not a true valid path, but it's just an attempt to give it to my Handler class below).
class Handler extends URLStreamHandler {
#Override
protected URLConnection openConnection(URL u) throws IOException {
return new URLConnection(u) {
#Override
public void connect() throws IOException {
}
#Override
public InputStream getInputStream() throws IOException {
System.out.println("IS: " + url);
return /*method to get input steam*/;
}
};
}
}
The /*method to get input steam*/ is set in my real code, but that's not relevant here. So any further ideas with this?

Categories

Resources