I've exported my Java console application to a Jar file, but when I run the jar and call code that parses in a JSON file I get a java.lang.IllegalArgumentException
Does anyone know why the exception is being thrown when I run the program as a JAR? The parsing works fine when the application is run from Eclipse.
This is the exact error that is output when I execute the jar file and call the code that parses the JSON file:
Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierar
chical
at java.io.File.<init>(Unknown Source)
at gmit.GameParser.parse(GameParser.java:44)
at gmit.Main.main(Main.java:28)
This is how the parsing is being done in my GameParser class:
public class GameParser {
private static final String GAME_FILE = "/resources/game.json";
private URL sourceURL = getClass().getResource(GAME_FILE);
private int locationId;
private List<Location> locations;
private List<Item> items;
private List<Character> characters;
public void parse() throws IOException, URISyntaxException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
// read from file, convert it to Location class
Location loc = new Location();
loc = mapper.readValue(new File(sourceURL.toURI()), Location.class);
Item item = mapper.readValue(new File(sourceURL.toURI()), Item.class);
GameCharacter character = mapper.readValue(new File(sourceURL.toURI()), GameCharacter.class);
// display to console
System.out.println(loc.toString());
System.out.println(item.toString());
System.out.println(character.toString());
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is the folder structure of my project:
The call getClass().getResource(GAME_FILE); will return a URL relative to this class. If you are executing your program from a JAR file, it will return a URL pointing to a JAR file.
Files in java can only represent direct filesystem files, not the ones in zip/jar archives.
To fix it:
Try to use getClass().getResourceAsStream() and use that instead of Files or
extract the files into some directory and use File in the same way as you are trying now.
This problem happen when you have two files with the same name,i mean in your project you have folder whith name "Images" and in your desktop you have other folder his name "images" automatically JVM choose desktop folder ,so if you want to confirm try to print your URI.Use this example to show your URI before creating your file
try {
URL location = this.getClass().getResource("/WavFile");
System.out.println(location.toURI());
File file = new File(location.toURI());
if (!file.exists()) {
System.out.println(file.mkdirs());
System.out.println(file.getAbsoluteFile());
}else
{
System.out.println(file.getPath());
}
} catch (Exception e) {
e.printStackTrace();
}
Related
I am creating a java app that will extract the embedded thumbnail inside of a Powerpoint (PPTX) document. Since pptx files are zip archives, I am trying to use TrueZip to get the thumbnail found inside of the archive. Unfortunately whenever I try running my application it throws an IOException stating that the file is missing C:\Users\test-user\Desktop\DocumentsTest\Hello.pptx\docProps\thumbnail.jpeg (missing file)
Below is the code I use to get the thumbnail:
public Boolean GetThumbPPTX(String inFile, String outFile)
{
try
{
TFile srcFile = new TFile(inFile, "docProps\\thumbnail.jpeg");
TFile dstFile = new TFile(outFile);
if(dstFile.exists())
dstFile.delete();
srcFile.toNonArchiveFile().cp_rp(dstFile);
return dstFile.exists();
} catch (IOException ex) {
Logger.getLogger(DocumentThumbGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
Where inFile is the absolute path of the pptx file and outFile is the path that the thumbnail will be copied to. I can verify that the archive does have a thumbnail inside of it at the same exact path.
Can someone help please?
I just found the answer. It seems I did not have the Zip driver configured correctly. I added this to my class constructor and it all works now:
TConfig.get().setArchiveDetector(new TArchiveDetector(
TArchiveDetector.NULL,
new Object[][] {
{ "zip|pptx", new ZipDriver(IOPoolLocator.SINGLETON)},
}));
I'm having a weird problem in java. I want to create a runnable jar:
This is my only class:
public class Launcher {
public Launcher() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
String path = Launcher.class.getResource("/1.png").getFile();
File f = new File(path);
JOptionPane.showMessageDialog(null,Boolean.toString(f.exists()));
}
}
As you can see it just outputs if it can find the file or not. It works fine under eclipse (returns true). i've created a source folder resources with the image 1.png. (resource folder is added to source in build path)
As soon as I export the project to a runnable jar and launch it, it returns false.
I don't know why. Somebody has an idea?
Thanks in advance
edit: I followed example 2 to create the resources folder: Eclipse exported Runnable JAR not showing images
If you would like to load resources from your .jar file use getClass().getResource(). That returns a URL with correct path.
Image icon = ImageIO.read(getClass().getResource("imageĀ“s path"));
To access images in a jar, use Class.getResource().
I typically do something like this:
InputStream stream = MyClass.class.getResourceAsStream("Icon.png");
if(stream == null) {
throw new RuntimeException("Icon.png not found.");
}
try {
return ImageIO.read(stream);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
stream.close();
} catch(IOException e) { }
}
Still you're understand, Kindly go through this link.
Eclipse exported Runnable JAR not showing images
Because the image is not separate file but packed inside the .jar.
Use the code to create the image from stream
InputStream is=Launcher.class.getResourceAsStream("/1.png");
Image img=ImageIO.read(is);
try to use this to get image
InputStream input = getClass().getResourceAsStream("/your image path in jar");
Two Simple steps:
1 - Add the folder ( where the image is ) to Build Path;
2 - Use this:
InputStream url = this.getClass().getResourceAsStream("/load04.gif");
myImageView.setImage(new Image(url));
I'm trying to run a SAXParser on a GAE application on a local XML file I stored in the WEB-INF file. It works fine when I use it on development mode but when I deploy it and try to parse that file I get the following exception, and I'm not writing am XML file, just trying to parse a local one:
java.security.AccessControlException: access denied ("java.io.FilePermission" "WEB-INF/MapInfo.xml" "write")
The code I'm trying to run looks like this:
#Override
public Double countPOIs() {
Double total = 0.0;
List<String> Coordinates;
Coordinates = new ArrayList<String>();
try {
XMLParser parser = new XMLParser(Coordinates, 8);
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(parser);
reader.parse("WEB-INF/MapInfo.xml");
total = parser.getACC();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return total;
}
The constructor seems a little strange but its irrelevant for this operation. Does anyone see any problems here?
Try replacing the reader.parse line with the following (sorry, unable to test it):
final javax.servlet.ServletContext servletContext = this.getServletContext();
java.io.InputStream stream = servletContext.getResourceAsStream("/WEB-INF/MapInfo.xml");
reader.parse(stream);
protected void executeInternal(JobExecutionContext context) throws JobExecutionException
{
System.out.println("Sending Birthday Wishes... ");
try
{
for(int i=0;i<maillist.length;i++)
{
Email email = new Email();
email.setFrom("spv_it#yahoo.com");
email.setSubject("Happy IndependenceDay");
email.setTo(maillist[i]);
email.setText("<font color=blue><h4>Dear Users,<br><br><br>Wish you a Happy Independence Day!<br><br><br>Regards,<br>Penna Cement Industries Limited</h4></font>");
byte[] data = null;
ClassPathResource img = new ClassPathResource("newLogo.gif");
InputStream inputStream = img.getInputStream();
data = new byte[inputStream.available()];
while((inputStream.read(data)!=-1));
Attachment attachment = new Attachment(data, "HappyBirthDay","image/gif", true);
email.addAttachment(attachment);
emailService.sendEmail(email);
}
}
catch (MessagingException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
}
This is the error I'm getting:
java.io.FileNotFoundException: class path resource [newLogo.gif] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:135)
at com.mail.schedular.BirthdayWisherJob.executeInternal(BirthdayWisherJob.java:55)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:66)
at org.quartz.core.JobRunShell.run(JobRunShell.java:223)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
The best practise is to read/write or to provide reference of any file is by mentioning the ABSOLUTE PATH of that file.
To your question, It shows the FileNotFoundException because, JVM failed to locate the file in your current directory which is by default your source path. So provide the absolute path in ClassPathResource or copy that image file to your current directory. It will solve your problem.
I think you need to put your file inside inside the src folder , if it's there then check whether it's under some directory which is inside the src directory.
Then give the correct location like given details below
src[dir]----->newLogo.gif
ClassPathResource img = new ClassPathResource("newLogo.gif");
or,
src[dir]----->images[dir]---->newLogo.gif
ClassPathResource img = new ClassPathResource("/images/newLogo.gif");
You got this error since the job is running in a separate quartz thread, I suggest that you locate your file newLogo.gif outside the jar and use the following to load it.
Thread.currentThread().getContextClassLoader().getResource("classpath:image/newLogo.gif");
I have small app and I tested and packed to jar and am trying to run it but I have error.
Here is my project structure:
src
-kie.template
----- ServerMain.java ==> Class with main
-kie.template.util
---- PropUtils.java
---- server.properties
target
-kietemplate.jar
---- lib
In the main method, PropUtils class reads properties.
public class PropUtils {
private static final String PROPERTIES = "server.properties";
public static Properties load() {
Properties properties = new Properties();
InputStream is = null;
try {
properties.load(PropUtils.class.getResourceAsStream(PROPERTIES));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is!=null) try{is.close();}catch(IOException e){}
}
return properties;
}
}
}
When I run the ServerMain class directly, it works fine. But after I packed it to jar and run, it shows error:
java -cp lib -jar kietemplate.jar
Caused by: java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:418)
at java.util.Properties.load0(Properties.java:337)
at java.util.Properties.load(Properties.java:325)
at au.org.jeenee.kie.template.util.PropUtils.load(PropUtils.java:26)
The properties file is in the directory when I look into the jar file.
jar tf kietemplate.jar
Any help would be appreciated very much.
EDIT:
I changed the logic to read properties:
Properties properties = new Properties();
InputStream is = null;
try {
File file = new File("server.properties");
is = new FileInputStream(file);
properties.load(new InputStreamReader(is));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is!=null) try{is.close();}catch(IOException e){}
}
It requires the properties file in parent directory of the jar file.
Your code works fine on my computer, both from the JAR and the filesystem.
A possible cause for that behaviour is the filesystem being case insensitive, but the jar file being case sensitive. But we really can't tell from the source code alone.