Java - accessing strings in non-compiled .java files during runtime - java

I've got a problem for you.
I've got a bunch of Java files (.java) sitting around and they all contain a class declaration and an array of strings. I need to do stuff with the array. What is the best way to access it?
I tried using JavaCompiler class, but that didn't seem to work - so should I use regex or something?
Here's a sample of what the files look like:
package com.mypack.costmgr;
public class Cost_en extends java.util.ListResourceBundle {
static final Object[][] contents = new String[][] {
{"ACTIVE", "ACTIVE"},
{"Joe", "asfag"},
{"lolcats", "cheezburger"},
{"HELP", "OH GOD NOT THE BEES"},
{"asdfffff", "hacks"}
};
public Object[][] getContents() {
return contents;
}
}
And there's probably a hundred of these files.
So, to summarize: what is the best way to gain access to that data?
(Obviously, I cannot simply compile them with my project.)

You have to compile the .java files and make them .class files. Then you put those .class files on your classpath. At this point you can now make a reference to the contents of each of those files. Since contents is static you can get a reference to it by doing the following:
class MyAwesomeClass
{
Object[][] myArray = Cost_en.contents;
}
Resource bundles

Spring Roo has an interesting Java language parser and manipulation framework for their plugins. It's used to extract info from user created .java files as part of the code supporting AspectJ. Maybe you can create a Roo plugin to handle what you're trying to do?

Related

Creating an 'Empty Shell' Jar

I'm looking on guidance on how I can essentially create an 'empty shell' jar with maven. The idea is I have a java project, and I want to export the my.project.api classes (with package) into its own jar without saving the methods / constructors actual code inside.
For example, lets say I have the following:
public class Test {
public void doSomething(String message) {
System.out.println(message);
}
}
I want to export a separate jar which would keep its package declaration, and export as:
public class Test {
public void doSomething(String message) {}
}
The reasoning for this is the project itself is exclusive, but I want to allow other developers to make their own integrations without the need of the physical product / project. This way by them hooking into say my.project.api.Test, they'd be able to see the methods and do as they wish.
Hopefully this clarifies enough, it would export as a separate jar maybe as 'MyProject-API.jar' or something.
Thanks!
This very much looks like a use case for interfaces.

Gradle generate sources.jar for only public interfaces

I am working on a closed-source Android library (published as an AAR), and want to include some javadocs for consumers, which requires a sources.jar.
I know I could cherry-pick each file using an includes property or maybe even a whole package/folder.
task('androidSourcesJar', type: Jar) {
classifier = 'sources'
baseName = artifactBaseName
from android.sourceSets.main.java.srcDirs
include ('MyInterface1.kt', 'MyInterface2.kt', 'MyInterface3.kt')
}
Instead, is there a way to include only public classes, interfaces, methods, etc? This seems like a problem that would've come up before.
You could try adding something like this, instead of your include:
from 'src/main/java'
eachFile { currentFile ->
String contents = new File(currentFile.getSourcePath()).text
if(!contents.contains("public class")) {
currentFile.exclude()
}
}
I'm not entirely sure if that works, but it should set you on the right path to where you want to go.
Since Gradle does not actually do any code analysis, you can't just simply say "only include files that have classes that are public". Instead, you have to either write a custom plugin that will only include public classes, or do something like what I provided. It includes everything from the source directory, but runs a little bit of code on each file. First, it gets the contents of the file, then it checks if that file contains public class. If not, the file does't have a public class, and should be excluded.
Hope this helps! Feel free to ask any more questions if you have any.

How to generate bytecode of existing class at Runtime in Java?

How to generate bytecode of existing class at Runtime in Java?
My Existing class is say Foo.java
public class Foo {
public String saySomething() {
return "Hello World";
}
}
Now I want to generate byte code of this existing class Foo.java and probably use it in another instance of JVM. Please understand I am not creating a class at runtime since I already have an existing class called Foo.java. Open to any libraries such as ASM or ByteBuddy etc.
[Edited following the clarification in the comments]
The following article describes how to compile a class from source code at runtime, using ToolProvider.getSystemJavaCompiler().
You do not need a library for that, any class file is just a resource just like any other file which can be located by Foo.class.getResource("Foo.class"). You can open a stream of this resource and read its byte just as of any other resource.
If you are already using Byte Buddy, you can get hold of the bytes by: ClassFileLocator.ForClassLoader.read(Foo.class) but if that is all you need, using a library would be an overkill.

Java with Beanshell to access fields and object with clean code

1). I know how to access the java fields and object in beanshell from my question Use java class fields in beanshell. However, it is not so clean way to implement as I need to first set the java variable in beanshell and then I can use it. However, in Jmeter it provides very clean way of using maps in beanshell similar way as we do in java, but JMeter has developed it's know library (class) which helps to access get/put methods for maps. I want to achieve similar way to access Map in beanshell.
I have checked JMeter for more information and I want to know that, I have created user define variable temp and assign value error, now in BSF process I just write a line vars.put('Name','temp Value') and it has updated value for temp variable. So, the question is I have not created JMeterVariables object vars but still beanshell allows to update values in map without setting any values as mention in your answer. I want to know how this works, need more depth information.
2). I have created my own class in java and in beanshell I am importing this class but it is giving Command not found: BSClass() below is the entire code
Java class
package test;
public class BSClass {
public void BSCMethod(){
System.out.println("I am from BSClass method BSCMethod");
}
}
sample.bsh
import test.BSClass;
c=BSClass();
c.BSCMethod();
print("I am from BeanShell Script");
Calling sample.bsh file java class
package test;
import java.io.FileNotFoundException;
import java.io.IOException;
import bsh.*;
public class DynamicVariable {
public static void main(String[] args) throws FileNotFoundException, IOException, EvalError {
new bsh.Interpreter().source("\\src\\test\\sample.bsh");
}
}
Note:
I don't need help in JMeter, it is to use in core java and beanshell.
All the files are in my project.
BSClass.class is under bin folder of my project
I would appreciate your inputs
In Beanshell you can add any Object you want including a Map
In JMeter, JMeterVariables is special implementation of Map that is added to Beanshell Interpreter before evaluate and also special Object as JMeterContext is added which even includes JMeterVariables inside. Code:
JMeterContext jmctx = JMeterContextService.getContext();
JMeterVariables vars = jmctx.getVariables();
try {
bshInterpreter.set("ctx", jmctx);//$NON-NLS-1$
bshInterpreter.set("Label", getName()); //$NON-NLS-1$
bshInterpreter.set("prev", jmctx.getPreviousResult());//$NON-NLS-1$
bshInterpreter.set("props", JMeterUtils.getJMeterProperties());
bshInterpreter.set("vars", vars);//$NON-NLS-1$
In your case with map you can do similar as you describe in comment:
bshInterpreter.set("myMap", javaMyMapObject);"
Then in Beanshell get the specific key from map:
myMap.get("aField");
To create class you should use new keyword, call:
c= new BSClass();
instead of c=BSClass();
If you create your own class, Class should be inside jar in relevant package .
The jar should be located in lib folder and not in bin folder, see JMeter's getting started:
Any jar file in such a directory will be automatically included in
user.classpath, jar files in sub directories are ignored. The given
value is in addition to any jars found in the lib directory. All
entries will be added to the class path of the system class loader and
also to the path of the JMeter internal loader.

Access classes from package

I'm developing an android test app and i'm going to access all internal class of android.view package. android.view is a package that is present in jar file. I tried by loading package name but it doesn't display the classes if any one tried
this already, please help.
Here's what I tried so far:
public static void main() throws ClassNotFoundException{
Class o =Class.forName("android.view");
Class[] C=o.getDeclaredClasses();
for(int i=0;i<C.length;i++) {
Classname = C[i].getName();
ClassesDisplayActivity.your_array_list3.add(Classname);
Log.i("Ramu","classname "+ C[i].getName());
}
}
}
It is not possible to determine at runtime all of the classes that are in a package using a standard class loader.
You might have some luck with this library though:
https://code.google.com/p/reflections/
Package is not a class. You cannot call Class.forName() for package and access classes that belong to class using getDelcaredClasses().
I do not know what do you really need, so I'd recommend you to explain this in separate question. probably you will receive better solutions.
However if you really need this you have to do the following:
Get your classpath by calling System.getProperty(java.class.path)
split this property to its elements by colon
iterate over the list and read each resource. If resource is jar you can use ZipInputStream, if it is a directory use File class.
filter list of resources you got at #3.
Fortunately you can use 3rd party library named Reflections that helps you to do all this without writing code.

Categories