Loading and executing jar file using custom ClassLoader - java

I want to load and execute jar file using custom ClassLoader.
My code:
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
public class Main {
private static JarClassLoader customClassLoader;
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IOException {
customClassLoader = new JarClassLoader(new File(args[0]).toURI().toURL());
customClassLoader.invokeClass(customClassLoader.getMainClassName(), new String[]{});
}
}
Everything works great with simple jars but when I want execute more complicated jars, they not always work properly. For example if program is using apache logging service I will see
"ERROR StatusLogger Unable to locate a logging implementation, using SimpleLogger"
How to get around this.

Related

I can't throws Exception and IOException in Java

I can't throws Exceptions such as IOException and Exception. I need to add dependencies of these but I couldn't find it.
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException; > It throws error: Cannot resolve symbol 'java' - Add Maven dependency
public class JsoupTest {
public static void main(String[] args) throws IOException { > Cannot resolve symbol 'IOException'
// download the HTML from wikipedia and parses it
final Document document = Jsoup.connect("http://en.wikipedia.org/").get();
// Select a bunch of a tags
final Elements newsHeadLines = document.select("#mp-itn b a");
// Prints to console
for(Element headline : newsHeadLines) { > foreach not applicable to type 'org.jsoup.select.Elements'
System.out.println(headline); > Cannot resolve symbol 'System'
}
}
}
My question can be basic but I'm pretty new on this sorry. If you give my answer please add these:
Where did you find this that dependency?
How can I find dependencies, because I checked Maven repository but I couldn't find.
Compiler throws error even for System.out.println method as I showed above, why is that?
Compiler throws error which I showed on belove, foreach not applicable to type 'org.jsoup.select.Elements'
Thank you for your all answers. I don't want directly dependency. I want it to know why. Thanks
You do not need to add a dependency to use IOException or System.
You probably did not use the compiler correctly or your IDE shows non-existent errors.

java cannot access javax.persistence.PersistenceException from Hibernate code

I'm setting up a very simple project, just trying to get a basic Hibernate setup without maven. I've downloaded the jar, put it under a /lib directory within my project and added this directory as a library under module settings. I can access Hibernate's classes and compile the project.
However, after declaring that the method throws a HibernateException (that extends PersistenceException), the code doesn't compile:
HibernateStatesMain.java:
package example;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Configuration;
public class HibernateStatesMain {
public static void main(String[] args) throws HibernateException {
Configuration config = new Configuration().configure();
}
}
And when I build, I get:
Error:(11, 24) java: cannot access javax.persistence.PersistenceException
class file for javax.persistence.PersistenceException not found
This should be a very simple thing, but I can't get my head around it. What am I doing wrong?

Unit Testing with different behaviour on existance of a file

There are some cases that the software shall behave differently according to some environmental conditions, for example whether a file exists at some place or not.
In my case, I'm developing a library, and it is configured according to a configuration file in classpath, (and falls back to default behavior if the config file does not exists).
How shall I unit test this class?
I need to write tests for evaluating the class in following cases:
the file does not exists on classpath
the file with content A exist on classpath
the file with content B exist on classpath
But I don't know how to configure environment to justify all of them. And execute the test one after each other.
By the way I'm using Java, and I have both JUnit and TestNG on the test classpath.
Edit:
One of the problems is that the config file resides in classpath, so if the normal ClassLoader finds and loads it, it returns the same content as long as the same class loader is used.
And I believe using a custom ClassLoader for testing is so complicated, that it needs tests to validate the tests!
You can use a temporary file created by your test to mock out the path in your class.
ConfigurationTest.java:
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeThat;
import java.nio.file.Files;
import org.junit.Test;
public class ConfigurationTest {
private Configuration config = new Configuration();
#Test
public void testWithConfigFile() throws Exception {
config.configFile = Files.createTempFile("config_",".ini");
config.configFile.toFile().deleteOnExit();
assertFalse(config.isInDefaultMode());
}
#Test
public void testWithoutConfigFile() throws Exception {
assumeThat(Files.exists(config.configFile), is(false));
assertTrue(config.isInDefaultMode());
}
}
Configuration.java:
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Configuration {
Path configFile = Paths.get("config.ini");
public boolean isInDefaultMode() {
return !Files.exists(configFile);
}
}

Access files under a package in java

I have the package structure something like this
src
main
java
com
org
-- Loader.java
resources
schemas
-- a.schema
-- b. schema
Now I want to be able to access the list of schemas under the schema folder which could vary with time from the Loader class. I package it as a jar and in runtime access all the files under the schema folder. How can I do it?
Do this inside Loader.java:
InputStream in = Loader.class.getResourceAsStream("/data/schemas/a.schema");
The leading slash means from starting from the root of classpath (i.e. your JAR file).
Using java 8, you should get it easily. See below code:
import java.util.stream.*;
import java.nio.file.*;
import java.util.*;
import java.io.*;
public class HelloWorld{
public static void main(String []args) throws IOException {
try (Stream<Path> filePathStream = Files.walk(Paths.get("/data/schemas/"))) {
List<File> filesInFolder = filePathStream.filter(Files::isRegularFile)
.map(Path::toFile)
.collect(Collectors.toList());
System.out.println(filesInFolder);
}
}
}
here the try-with-resource constructs ensures that the stream is closed automatically after using.

Setting Up Log4J in IntelliJ IDEA 13

I'm building a simple app in IntelliJ IDEA 13 and can't seem to figure out how to get log4j working. My app is a simple demo that I made to make sure I could build something functional, all it does is multiply two random numbers and uses apache tomcat to put it on a localhost that I can access via my browser.
Here is the class code:
package Sample;
log4j-api-2.0.jar;
log4j-core-2.0.jar;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
public class HelloWorld {
public static double getMessage() {
return Math.random()* Math.random();
}
private static Logger log = LogManager.getRootLogger();
log.debug("Debugging Message");
log.info("Informational message");
log.warn("Warning Message");
System.in.read();
}
I'm getting the error "class or interface expected" at the import lines and jar file lines so I don't think I've placed the corresponding files in the right directory. That's also causing the rest of the logging lines (from private static Logger... on) to generate errors.
1. The following isn't valid Java:
log4j-api-2.0.jar;
log4j-core-2.0.jar;
You only need the import lines, e.g.,
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
2. The .jar files must be associated with your project.
You can:
Right-click the "External Libraries" section and add them that way, or...
Use Maven and add them as project dependencies, or...
Use some other dependency management and/or build tool, e.g., Ant + Ivy, Gradle, etc.
3. You need to move the logging statements into a place where code is valid, like in a method:
package sample;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
public class HelloWorld {
private static final Logger log = LogManager.getRootLogger();
public static void main(String[] args) {
log.debug("Debugging Message");
log.info("Informational message");
log.warn("Warning Message");
}
}

Categories