I'm trying to make a simple graph using java but keep getting error
Code:
public class PlantUMLDemoMain {
public static void main(String[] args) throws Exception {
generateFromStringSource(new File("from-string.png"));
generateFromApi(new File("from-api.png"));
}
private static void generateFromApi(File file) throws IOException {
// 1. setup:
SequenceDiagramFactory f = new SequenceDiagramFactory();
SequenceDiagram diagram = f.createEmptyDiagram();
// 2. Build the diagram:
// "Bob -> Alice : hello"
// See net.sourceforge.plantuml.sequencediagram.command.CommandArrow#executeArg
Display bobD = Display.getWithNewlines("Bob");
Participant bobP = diagram.getOrCreateParticipant("Bob", bobD);
Display aliceD = Display.getWithNewlines("Alice");
Participant aliceP = diagram.getOrCreateParticipant("Alice", aliceD);
Display label = Display.getWithNewlines("hello");
ArrowConfiguration config = ArrowConfiguration.withDirectionNormal();
Message msg = new Message(bobP, aliceP, label, config, diagram.getNextMessageNumber());
checkState(null == diagram.addMessage(msg));
// 3. Output the diagram
// See net.sourceforge.plantuml.SourceStringReader#generateImage
diagram.makeDiagramReady();
checkState(1 == diagram.getNbImages());
try (OutputStream os = new FileOutputStream(file)) {
ImageData imageData = diagram.exportDiagram(os, 0, new FileFormatOption(FileFormat.PNG));
System.out.println("generateFromApi: " + diagram.getDescription().getDescription());
}
}
private static void generateFromStringSource(File file) throws IOException {
String source = "#startuml\n";
source += "Bob -> Alice : hello\n";
source += "#enduml\n";
StringBuffer stringBuffer = new StringBuffer();
SourceStringReader reader = new SourceStringReader(source);
// Write the first image to "png"
String desc = reader.generateImage(file);
// Return a null string if no generation
System.out.println("generateFromStringSource: " + desc);
}
}
Error: Exception in thread "main" java.lang.IllegalAccessError: class net.sourceforge.plantuml.png.PngIOMetadata (in unnamed module #0x9597028) cannot access class com.sun.imageio.plugins.png.PNGMetadata (in module java.desktop) because module java.desktop does not export com.sun.imageio.plugins.png to unnamed module #0x9597028
at net.sourceforge.plantuml.png.PngIOMetadata.writeWithMetadata(PngIOMetadata.java:60)
at net.sourceforge.plantuml.png.PngIO.write(PngIO.java:86)
at net.sourceforge.plantuml.png.PngIO.write(PngIO.java:80)
at net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d.writeImageTOBEMOVED(UGraphicG2d.java:219)
at net.sourceforge.plantuml.ugraphic.ImageBuilder.writeImageInternal(ImageBuilder.java:249)
at net.sourceforge.plantuml.ugraphic.ImageBuilder.writeImageTOBEMOVED(ImageBuilder.java:171)
at net.sourceforge.plantuml.sequencediagram.graphic.SequenceDiagramFileMakerPuma2.createOne(SequenceDiagramFileMakerPuma2.java:234)
at net.sourceforge.plantuml.sequencediagram.SequenceDiagram.exportDiagramInternal(SequenceDiagram.java:222)
at net.sourceforge.plantuml.UmlDiagram.exportDiagramNow(UmlDiagram.java:236)
at net.sourceforge.plantuml.AbstractPSystem.exportDiagram(AbstractPSystem.java:127)
at net.sourceforge.plantuml.SourceStringReader.generateImage(SourceStringReader.java:124)
at net.sourceforge.plantuml.SourceStringReader.generateImage(SourceStringReader.java:111)
at net.sourceforge.plantuml.SourceStringReader.generateImage(SourceStringReader.java:101)
at scr.graphviz.sk.PlantUMLDemoMain.generateFromStringSource(PlantUMLDemoMain.java:66)
at scr.graphviz.sk.PlantUMLDemoMain.main(PlantUMLDemoMain.java:23)
I found someone with similar problem and older version of plantuml worked for him. I have jar file of the older version but I'm not sure how to apply it. I tried inspecting the file and find out versions of libraries used and added maven dependencies for them but it didnt seem to work.
This is similar problem i mentioned https://github.com/plantuml/plantuml/issues/69
Related
My Question:
Is it possible to get a Uri from an import of a third party dependency?
Question Context:
I am trying to get a list of classes accessed with the following.
import com.name.*
In the context in which I want to use it, I will not be able to use third party dependencies. I do however need to find all classes associated with a third party dependency import.
I have found one such answer to my issue in the following code, provided by the user tirz.
public static List<Class<?>> getClassesForPackage(final String pkgName) throws IOException, URISyntaxException {
final String pkgPath = pkgName.replace('.', '/');
final URI pkg = Objects.requireNonNull(ClassLoader.getSystemClassLoader().getResource(pkgPath)).toURI();
final ArrayList<Class<?>> allClasses = new ArrayList<Class<?>>();
Path root;
if (pkg.toString().startsWith("jar:")) {
try {
root = FileSystems.getFileSystem(pkg).getPath(pkgPath);
} catch (final FileSystemNotFoundException e) {
root = FileSystems.newFileSystem(pkg, Collections.emptyMap()).getPath(pkgPath);
}
} else {
root = Paths.get(pkg);
}
final String extension = ".class";
try (final Stream<Path> allPaths = Files.walk(root)) {
allPaths.filter(Files::isRegularFile).forEach(file -> {
try {
final String path = file.toString().replace('/', '.');
final String name = path.substring(path.indexOf(pkgName), path.length() - extension.length());
allClasses.add(Class.forName(name));
} catch (final ClassNotFoundException | StringIndexOutOfBoundsException ignored) {
}
});
}
return allClasses;
}
The problem I have with the code above is that where final URI pkg is assigned. This works with a package that exists within the project, but if an import for a third party dependency is used this throws a NullPointerException. Is it possible to make this code work for third party dependencies? Might this require some reference to an .m2 folder or other library resource?
public class TestResourceBundle {
private static final Path frZoo = Paths.get("./src/Zoo_fr.properties");
private static final Path enZoo = Paths.get("./src/Zoo_en.properties");
private static void createFiles() {
try {
Files.createFile(frZoo);
Files.createFile(enZoo);
try (BufferedWriter enWriter = Files.newBufferedWriter(enZoo);
BufferedWriter frWriter = Files.newBufferedWriter(frZoo);) {
enWriter.write("hello=Hello\nopen=The zoo is open");
frWriter.write("hello=Bonjour\nopen=Le zoo est ouvert");
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void createBundle() {
Locale us = new Locale("en", "US");
Locale france = new Locale("fr", "FR");
ResourceBundle usBundle = ResourceBundle.getBundle("Zoo", us);
ResourceBundle frBundle = ResourceBundle.getBundle("Zoo", france);
System.out.println(usBundle.getString("hello"));
System.out.println(frBundle.getString("hello"));
}
}
In the main function, if I run the following, it will throw java.util.MissingResourceException
public static void main(String[] args) {
createFiles();
createBundle();
}
but if I run these two functions separately (in two programs), it works and does not have any problem.
First run
public static void main(String[] args) {
createFiles();
// createBundle();
}
then run the following, in this case, it works
public static void main(String[] args) {
// createFiles();
createBundle();
}
I don't know why, please help
The problem is that you are trying to load a bundle that is not present in the classpath the application knows about.
When you call ResourceBundle.getBundle it will try to load the resource bundle from the application classpath. But the application classpath was already defined at the application startup, so your brand new files are not listed there.
Two options I can think of: Load the bundle from a file input stream or, define your own classloader to load the files.
1. Load the bundle from a File Input Stream
Create a new PropertyResourceBundle from a FileInputStream that loads each file directly.
Warning: Stream closing and exception handling omitted for brevity.
FileInputStream enFileStream = new FileInputStream("./src/Zoo_en.properties");
FileInputStream frFileStream = new FileInputStream("./src/Zoo_fr.properties");
ResourceBundle usBundle = new PropertyResourceBundle(enFileStream);
ResourceBundle frBundle = new PropertyResourceBundle(frFileStream);
2. Create a URL ClassLoader to load the new files
This is a more scalable approach. Create a new URLClassLoader and use that class loader as an argument for getBundle.
Warning: Stream closing and exception handling omitted for brevity.
File bundleRootPath = new File("./src");
URL[] urls = new URL[]{bundleRootPath.toURI().toURL()};
ClassLoader classLoader = new URLClassLoader(urls);
ResourceBundle usBundle = ResourceBundle.getBundle("Zoo", us, classLoader);
ResourceBundle frBundle = ResourceBundle.getBundle("Zoo", france, classLoader);
Hope that helps.
How do I go about configuring the classpath when using the scripts package with atom/java?
I know my classpath is:
usr/local/algs4/algs4.jar
Here is the code I am testing with:
import edu.princeton.cs.algs4.*;
public class Wget {
public static void main(String[] args) {
// read in data from URL
String url = args[0];
In in = new In(url);
String data = in.readAll();
// write data to a file
String filename = url.substring(url.lastIndexOf('/') + 1);
Out out = new Out(filename);
out.println(data);
out.close();
}
}
Since you're using algs4, Use Princeton's site and search for classpath.
http://algs4.cs.princeton.edu/code/
I am serialising an already trained classifier on my Computer and I am trying to deserialize it on Android. However, when I try to deserialize it on my Android Device I see this log in the console:
W/System.err: java.io.InvalidClassException: weka.classifiers.meta.LogitBoost;
Incompatible class (SUID): weka.classifiers.meta.LogitBoost: static final long serialVersionUID =-1105660358715833753L;
but expected weka.classifiers.meta.LogitBoost: static final long
serialVersionUID =-3905660358715833753L;
W/System.err: at java.io.ObjectInputStream.verifyAndInit(ObjectInputStream.java:2336)
Not sure what to do. I have to mention that I am using a stripped version of WEKA available here.
This is my classifier class used to train and serialize the classifier on my computer:
public class ClassifierSerializer {
//variables//
public ClassifierSerializer(String classifierName,
String classifierParameters,
String dataSourceFile,
String outputFileName) {
this.classifierName = classifierName;
this.classifierParameters = classifierParameters;
this.dataSourceFile = dataSourceFile;
this.outputFileName = outputFileName;
}
/**
* Output the trained classifier to the specified file
*/
public void serialize() {
readFile();
train();
writeToFile();
}
private void train() {
classifier = AbstractClassifier.forName(classifierName, Utils.splitOptions(classifierParameters));
classifier.buildClassifier(dataset);
}
private void writeToFile() {
// Serialize classifier
FileOutputStream fileStream;
fileStream = new FileOutputStream(outputFileName);
ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
objectStream.writeObject(classifier);
objectStream.close();
fileStream.close();
}
}
This is how I am using it in my main method:
public static void main(String[] args) throws Exception {
String datasource = "C:\\Users\\Georgi\\Desktop\\HAR_training.arff";
ClassifierSerializer classifierSerializer = new ClassifierSerializer(
"weka.classifiers.meta.LogitBoost",
"-P 100 -L -1.7976931348623157E308 -H 1.0 -S 1 -I 10 -W weka.classifiers.trees.DecisionStump",
datasource,
"logit.data");
classifierSerializer.serialize();
}
And this is how I am deserializing it on Android (I have the fine in my assets folder):
private Classifier getClassifier() {
// Add logic to make a network call to download the trained offline model/classifier
String filename = "logit.data";
ObjectInputStream objectStream = new ObjectInputStream(getAssets().open(filename));
Object obj =objectStream.readObject();
if (obj instanceof Classifier) {
return (Classifier) obj;
} else {
return null;
}
}
I found out what was going on (kind of). I decided to replace the full weka.jar library in my InteliJ project on my PC with the same stripped version of the weka library that I am using on my Android Project. For some reason that solved the problem. I assume, the versions were a bit different and some change differences were causing the problem.
Frankly, I do not know even it is possible or not.
But what I am trying to do is just like below.
I made a class file from ClassFile.java via javac command in terminal.
Then I want to get an instance from .java file or .class file.
Next, I made another project in eclipse, As you guess this project path and upper file path are completely different. For instance, ClassFile.java/class file can be located in '~/Downloads' folder, the other hand, new eclipse project can be in '~/workspace/'.
So I read file which referred in step 1 by FileInputStream.
From here, I just paste my code.
public class Main {
private static final String CLASS_FILE_PATH =
"/Users/juneyoungoh/Downloads/ClassFile.class";
private static final String JAVA_FILE_PATH =
"/Users/juneyoungoh/Downloads/ClassFile.java";
private static Class getClassFromFile(File classFile) throws Exception {
System.out.println("get class from file : [" + classFile.getCanonicalPath() + " ]");
Object primativeClz = new Object();
ObjectInputStream ois = null;
ois = new ObjectInputStream(new FileInputStream(classFile));
primativeClz = ois.readObject();
ois.close();
return primativeClz.getClass();
}
public static void main(String[] args) throws Exception {
getClassInfo(getClassFromFile(new File(CLASS_FILE_PATH)));
}
}
just like your assumption, this code has errors.
For example, it shows :
java.io.StreamCurruptedException: invalid stream header : CAFEBABE
this there any way to get object instance from .class file or .java file?
P.S.
I wish do not use extra libraries.
private static final String CLASS_FOLDER =
"/Users/juneyoungoh/Downloads/";
private static Class getClassFromFile(String fullClassName) throws Exception {
URLClassLoader loader = new URLClassLoader(new URL[] {
new URL("file://" + CLASS_FOLDER)
});
return loader.loadClass(fullClassName);
}
public static void main( String[] args ) throws Exception {
System.out.println((getClassFromFile("ClassFile"));
}