I have written a program that checks a data set and provides a result, i.e. if a climate condition is given for 1000 days as data set to the program it will find any deviation in the program and provide as result that major deviation.
package main;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import faster94.*;
import rules_agarwal.*;
import algo_apriori.*;
import context_apriori.*;
import itemsets.*;
public class MainTestAllAssociationRules {
public static void main(String [] arg){
ContextApriori context = new ContextApriori();
try {
context.loadFile(fileToPath("ds1.txt"));
}
catch(Exception e)
{
e.printStackTrace();
}
/*catch (IOException e) {
e.printStackTrace();
}*/
context.printContext();
double minsupp = 0.5;
AlgoApriori apriori = new AlgoApriori(context);
Itemsets patterns = apriori.runAlgorithm(minsupp);
patterns.printItemsets(context.size());
double minconf = 0.60;
AlgoAgrawalFaster94 algoAgrawal = new AlgoAgrawalFaster94(minconf);
RulesAgrawal rules = algoAgrawal.runAlgorithm(patterns);
rules.printRules(context.size());
}
public static String fileToPath(String filename) throws UnsupportedEncodingException{
URL url = MainTestAllAssociationRules.class.getResource(filename);
return java.net.URLDecoder.decode(url.getPath(),"UTF-8");
}
}
The above is the main program. There are seven files and I have created by own package, but when I run this program as a whole I cannot run it. It complains that a package is missing. i have ready provided all the seven files.
Can any one be able to run those files?
Directory tree has to reflect package tree.
So if you have a class in a package named main you class file must be in a directory named main under the working directory. So if you execute from bin/ your class must be in bin/main.
Hope this helps
Edit
The directory tre has to look like this.
bin/
-----faster94/
--------------Classes or Subpackage
-----rules_agarwal/
-------------------Classes or Subpackage
-----algo_apriori/
------------------Classes or Subpackage
-----context_apriori/
---------------------Classes or Subpackage
-----itemsets/
--------------Classes or Subpackage
-----main/
----------MainTestAllAssociationRules and other classes or subpackages
To run this use java main.MainTestAllAssociationRules in the root (bin/) directory
Related
I have a spring application with multiple dependent libraries that have the inner properties/xml that I want to read.
test-app.jar
dep1.jar
dep2.jar
dep3.jar
...
Each of the dep1/2/3 jars have the file called META-INF/config.properties which contains the files to further read within that dependent jars.
I tried the ResourceUtils.getURL("classpath:/META-INF/config.properties"), but it always reads from the first dependent file.
How can I read from each jars that contains the same name?
I found this solution after searching:
final Enumeration<URL> resEnum =
MyClass.class.getClassLoader()
.getResources("META-INF/config.properties");
final List<URL> resources =
Collections.list(resEnum);
//Copied from riptutorial.com
Refs:
https://riptutorial.com/java/example/19290/loading-same-name-resource-from-multiple-jars
https://stackoverflow.com/a/6730897
Updated solution:
package abc;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
public class MultipleClasspathEntries {
public static void main(String[] args) throws IOException {
final Enumeration<URL> resEnum =
MultipleClasspathEntries.class.getClassLoader()
.getResources("META-INF/MANIFEST.MF");
while (resEnum.hasMoreElements()) {
System.out.println(resEnum.nextElement());
}
}
}
//Copied from riptutorial.com
$JAVA_HOME/bin/javac abc/*.java
$JAVA_HOME/bin/java -cp /c/so-67847004/commons-lang-2.4.jar:/c/so-67847004/commons-collections-3.2.1.jar:. abc.MultipleClasspathEntries
Output:
jar:file:/C:/so-67847004/commons-lang-2.4.jar!/META-INF/MANIFEST.MF
jar:file:/C:/so-67847004/commons-collections-3.2.1.jar!/META-INF/MANIFEST.MF
I've been trying to import a .class via absolute path while code is running and I don't know how to do it.
I found a way to import a class when it's already in project's build path by Class.forName();but I need to find a way to load a class that is not in build path.
The goal is:
User is able to upload his own .class file which is then saved locally to a specific folder and path is saved in database
Via GUI user can select this file to be used while code is running
My code should load a class via this given absolute path while code is running
The problem is with 3rd point because I don't know if it is possible to load a class while code is running.
I've tried using URLClassLoader but I'm getting ClassNotFound error.
EDIT:
Basically, I have this static function which should return Class by it's name, but urlClassLoader.loadClass() throws error.
Name of a file is J48.class so for className argument I've tried using "J48", "J48.class" but none work.
Additionaly I've tried setting folder classifiers to build path and setting argument to "weka.classifiers.trees.J48" which is full path with package to this class (package structure is weka.classifiers.trees).
`public static Class getClassByName(String className) throws MalformedURLException, ClassNotFoundException
{
URLClassLoader urlClassLoader = URLClassLoader.newInstance(new URL[] {
new URL("file:///D:\\xampp\\htdocs\\prog-ing\\classifiers\\")
});
Class class = urlClassLoader.loadClass(className);
return class;
}`
I think I have a suggestion to solve your problem...
I know two options:
Option 1: Read a class file from directory.
Example:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Test5 extends ClassLoader {
private static final String PATH = "C://myFiles//";
public static void main(String[] args) {
Class clazz = getClassFromName("Test4");
System.out.println(clazz);
}
private static Class getClassFromName(String className) {
File file = new File(PATH + className + ".class");
try {
FileInputStream fileInputStream = new FileInputStream(file);
byte[] bytes = new byte[fileInputStream.available()];
fileInputStream.read(bytes);
return defineClass(className, bytes, 0, bytes.length);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
This will print something like this:
class Test4
- Option 2: Read a class file from JAR.
Example:
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class Test5 {
private static final String PATH = "C://myFiles//";
public static void main(String[] args) {
Class clazz = getClassFromFile("myJar.jar", "com.mypackage.Test4");
System.out.println(clazz);
}
private static Class getClassFromFile(String fromFile, String className) {
try {
URL url = new URL("file:////" + PATH + fromFile);
URLClassLoader urlClassLoader = URLClassLoader.newInstance(
new URL[] {
url
});
return urlClassLoader.loadClass(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
}
This will print something like this:
class com.mypackage.Test4
Note that to read a jar file I had to put the full path of package to the class file.
I hope I've helped.
Okay so after thinking a bit, I only got to the one solution (still not satisfied with it) which is following:
every class that needs to be uploaded by user is saved into workspace of this project and therefore I am able to get class using Class.forName(); pointing out this "folder" of uploaded classes, in my case: Class.forName("classifiers.className");
I'm attempting to use some other jar files that have functions I'd like to access. The are public, and I have sample code I built my test app from. It appears to be signing related (ie they are signed, mine was self-signed).
When I attempt to load the applet in a webpage I am asked if I wish to block or unblock. If I tell it to unblock I get the following error:
class "Scanx" does not match the trust level of other classes in the same package.
I've read at least a dozen different articles but they either don't apply or exceed my ability to understand at my current level of Java coding knowledge.
I'd really appreciate any thoughts on how to get past this so I can test & complete my java applet? Code is below:
<html><body>
<applet id=scanx name=scanx code="Scanx.class" height="600" width="600" archive="./Scanx.jar,./ij.jar,./plugin.jar,./twain.jar"></applet>
<script type="text/javascript">
function scanit()
{
document.scanx.getScan();
}
</script>
<input type=button onclick="scanit();">
</body></html>
Here's my java code, which I compile into a jar using "jar cvf Scanx.jar Scanx.java" ...
package uk.co.mmscomputing.device.twain.applet;
import javax.swing.JApplet;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.awt.image.RasterFormatException;
import javax.imageio.ImageIO;
import netscape.javascript.*;
import java.io.File;
import uk.co.mmscomputing.device.scanner.Scanner;
import uk.co.mmscomputing.device.scanner.ScannerListener;
import uk.co.mmscomputing.device.scanner.ScannerDevice;
import uk.co.mmscomputing.device.scanner.ScannerIOException;
import uk.co.mmscomputing.device.scanner.ScannerIOMetadata;
public class xScanx extends JApplet implements ActionListener, ScannerListener{
int index = 0;
String filename;
Scanner scanner;
public Scanx(){
}
public Scanx(String title, String[] argv){
init();
}
public void init(){
scanner=Scanner.getDevice();
scanner.addListener(this);
// scanner.select("TWAIN_32 Sample Source");
}
public void getScan()
{
try{
scanner.acquire();
}catch(ScannerIOException se){
se.printStackTrace();
}
}
public void actionPerformed(ActionEvent evt){
/*
try{
if(evt.getSource()==acquireButton){
scanner.acquire();
}else if(evt.getSource()==selectButton){
scanner.select();
}else if(evt.getSource()==cancelButton){
scanner.setCancel(true);
}
}catch(ScannerIOException se){
se.printStackTrace();
}
*/
}
public void update(ScannerIOMetadata.Type type, ScannerIOMetadata metadata){
if(type.equals(ScannerIOMetadata.ACQUIRED)){
BufferedImage image=metadata.getImage();
System.out.println("Have an image now!");
try{
ImageIO.write(image, "jpg", new File(filename+index+".jpg"));
index++;
// new uk.co.mmscomputing.concurrent.Semaphore(0,true).tryAcquire(2000,null);
}catch(Exception e){
e.printStackTrace();
}
}else if(type.equals(ScannerIOMetadata.NEGOTIATE)){
ScannerDevice device=metadata.getDevice();
}else if(type.equals(ScannerIOMetadata.STATECHANGE)){
System.err.println(metadata.getStateStr());
}else if(type.equals(ScannerIOMetadata.EXCEPTION)){
metadata.getException().printStackTrace();
}
}
public static void main(String[] argv){
try{
new Scanx("Twain Applet Example [2007-11-02]", argv);
}catch(Exception e){
e.printStackTrace();
}
}
}
The reported error message looks similar to the error when having two classes in the same package with different signatures. This has been illegal since back in the nineties. One of the differences is that the fully qualifies class name should be reported (it is about packages). It may be the case that the class is in fact in a default package, never a good idea. That would typically because the package name was added later, but an old class file that has hung around is being used.
The applet tag looks a bit wrong. code="Scanx.class" should have the package name in, which further suggests a stale class file. plugin.jar appears to be part of the PlugIN, so shouldn't be included when run in the plugin (but it will be necessary when compiling the code).
Then you say 'I compile into a jar using "jar cvf Scanx.jar Scanx.java"'. A little bit confusing. You should compile the .java file into a .class with javac. Then use jar to create the jar. The files you want should be .class not .java and should include the package name. If you look at the jar as a zip, it should have classes inside with directory paths matching package names (IIRC, jar tf Scanx.jar should list the files).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Execute another jar in a java program
Basically I want to run an external .jar from the one I'm working on now.
I.e. I want to run foo.jar from bar.jar
I've tried using Runtime and Process to execute "java -jar foo.jar", but it opens foo.jar and then it closes immediately. Any tips?
The easiest solution (as Thorn pointed out) would be to have the jar as a build-time dependency and invoke it statically from your code:
ExternalJarMainClass.main(new String[]{"arguments", "to", "main"});
But if that is not possible, you can use a URLClassLoader to load the jar dynamically. If the jar is indeed runnable, then you can read the main class from META-INF/MANIFEST.MF and invoke main via reflection.
This is a different approach from creating a separate process, as the external code will run in the same process as your application. Perhaps this is desirable, perhaps not - that depends on the situation.
Below's a (hastily written and flawed) sample helper class that does just that.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JarRunner {
private final Method entryPoint;
public JarRunner(File jarFile) throws
ClassNotFoundException,
IOException,
NoSuchMethodException {
URL jarUrl = jarFile.toURI().toURL();
URLClassLoader loader = URLClassLoader.newInstance(
new URL[]{jarUrl});
URL manifestUrl = loader.findResource("META-INF/MANIFEST.MF");
String manifest = resourceToString(manifestUrl);
Class<?> clazz = loader.loadClass(findMainClassName(manifest));
entryPoint = clazz.getMethod("main", String[].class);
}
public void run(String[] argsToMain) throws
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException {
entryPoint.invoke(null, (Object) argsToMain);
}
private static String resourceToString(URL url) throws IOException {
InputStream contentStream = url.openStream();
try {
BufferedReader r = new BufferedReader(
new InputStreamReader(contentStream));
StringBuilder sb = new StringBuilder();
String line = null;
do {
line = r.readLine();
if (line != null) {
sb.append(line).append('\n');
}
} while (line != null);
return sb.toString();
} finally {
contentStream.close();
}
}
private static String findMainClassName(String manifest) {
Matcher m = MAIN_CLASS_PATTERN.matcher(manifest);
if (m.find()) {
return m.group(1);
}
return null;
}
private static final Pattern MAIN_CLASS_PATTERN =
Pattern.compile("Main-Class: (.+)");
}
Sample usage:
JarRunner jr = new JarRunner(new File("path/to/MyJar.jar"));
jr.run(new String[]{"arg1", "arg2"});
Can you run foo.jar directly? Does it have a manifest with a main method?
I am guessing that you can. So you want to launch the main method inside of a class like foo.Main
Option 1: Include foo.jar in the classpath. If you are using an IDE, then this just means adding foo.jar as a library. Now you are free to import the package (lets call the package foo) and launch your second java program from a single line of Java code:
foo.Main.main(null);
Most likely you would want to do this in a separate thread:
class FooRunner extends Thread {
public void run() {
foo.Main.main(null);
}
}
and then you would launch with this:
FooRunner secondaryApp = new FooRunner();
secondaryApp.start();
Option 2
You can load the classes in the Foo package at runtime using a class loader.
See the Javadocs for java.lang.ClassLoader and this example of a CustomClassLoader
Check java -jar foo.jar runs correctly from command line. Also ensure java is there in the path. It may be better to provide absolute path to java.exe in the arguments.
Please consider using ProcessBuilder instead of Runtime.
Using a sample from xSocket which will run xSocketHandler as a new process, I want to customize and moving all of these code into other java file, can I copy public class xSocketDataHandler implements IDataHandler and paste into different filename say main.java?
import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.channels.ClosedChannelException;
import org.xsocket.*;
import org.xsocket.connection.*;
public class xSocketDataHandler implements IDataHandler
{
public boolean onData(INonBlockingConnection nbc) throws IOException, BufferUnderflowException, ClosedChannelException, MaxReadSizeExceededException
{
try
{
String data = nbc.readStringByDelimiter("\0");
//nbc.write("Reply" + data + "\0");
nbc.write("+A4\0");
if(data.equalsIgnoreCase("SHUTDOWN"))
xSocketServer.shutdownServer();
}
catch(Exception ex)
{
System.out.println(ex.getMessage());
}
return true;
}
}
No, you can't do that without reducing the visibility of xSocketDataHandler to default. If you don't want to do that, your file name should be xSocketDataHandler.java
You must be having class xSocketDataHandler in a file of the same name already since it is public. You could move other non public classes in this file to Main.java instead.
A public class will need to be in a file named according to the class, so in this case it would be xSocketDataHandler.java.
Convention is also to name java classes starting with an upper-case letter, so it would be public class XSocketDataHandler and file XSocketDataHandler.java. This isn't required, though.