java value object - java

I'm new to Java and I have to create a value object, (maybe it's called mapped object in Java) but my code doesn't seem to work, here is the value object:
package ....;
public class User {
private int id;
private int uid;
private String name;
public User()
{
// do something here
}
}
and I assign a new value object like this:
public boolean some_function()
{
User u = new User();
return true; // got a breakpoint here
}
So if I comment out "User u = new User();" I will go to the breakpoint but if I keep it like above it will just stop running.
On a side note, I keep both the files in the same folder so eclipse doesn't import the file, is this correct or should I import it?
EDIT:
After some time I found out that I had to import the file manually, I thought I tried that but apparently I didn't.

Dennis, if the code as you posted it is the exact code you're running, then this makes no sense -- the "User u = new User();" call would return you a new User object without any issues, since your constructor is empty.
To demonstrate that to yourself, change your constructor to:
public User() {
System.out.println("I'm inside the User constructor!");
}
and call your some_function() function again. You should see that line printed out to your console.
Given what you're reporting and the code you're showing, I suspect that the class that contains some_function() isn't "seeing" the User class -- you're importing some other User class rather than the one you created. Are the two classes -- the User class and the class which contains some_function() -- in the same package? If not, what import statement at the top of the some_function()-containing class is handling the import of your User class?

Sure you don't have an infinite loop in your User() constructor?

Put some code into the constructor, for example
id = 99;
set a break point there.
I don't understand what you mean about importing into Eclipse - I have all my code in Eclipse - however I suspect that your application is not correctly seeing the User class. Maybe you are even getting a compilation error. Create your packages and classes in Eclipse, let it sort out the directories for you.
Show us the whole app class , including the import of User.

Put the breakpoint on User u = new User(); and step into the constructor to see what it's doing.

Related

Import classes in method?

I'm customizing a PLM Windchill Workflow, which provides a mechanism to execute java code snippets. Unfortunately, they are 'inserted' into prepared service's method, which means that there is no way to import classes, so I have to include full package names to use it. Don't try to understand the snippet below, just look how does it looks like:
wt.fc.QueryResult activities = wt.fc.PersistenceHelper.manager.find((wt.pds.StatementSpec) activitiesQuery);
while (activities.hasMoreElements()) {
wt.workflow.work.WfAssignedActivity activity = (wt.workflow.work.WfAssignedActivity) activities.nextElement();
if(activity.getDisplayIdentifier().toString().equals("Analyze Image Request")){
java.util.List<wt.workflow.work.WorkItem> workItems = wt.workflow.status.WfWorkflowStatusHelper.service.getWorkItems(activity);
for (wt.workflow.work.WorkItem workItem : workItems){
String action = workItem.getActionPerformed();
if(action != null && action.equals("Accepted")){
wt.org.WTPrincipalReference approver = workItem.getOwnership().getOwner();
n_approver = approver.getFullName() + " ("+approver.getDisplayName()+")";
wt.fc.collections.WTHashSet approverSet = new wt.fc.collections.WTHashSet(java.util.Arrays.asList(approver));
wt.project.Role role = wt.project.Role.toRole("APPROVER");
com.ptc.windchill.pdmlink.change.server.impl.WorkflowProcessHelper.setChangeItemParticipants(report, role, approverSet);
break;
}
}
break;
}
}
And my question is - how to make this code any more readable? Of course there is no way to import classes inside the method, there is even no way to divide this snippet into separate methods (as it is 'pasted' into one) so I'm looking for other ideas.
One option to make the code more readable would be to separate chained method/property calls across multiple lines.
For example, this line:
wt.project.Role role = wt.project.Role.toRole("APPROVER");
could be rewritten as:
wt.project.Role role = wt
.project
.Role
.toRole("APPROVER");
You can call this complete code from a Customized Java class.
You just have to call your class and take the final parameters required from the Java class to make it more readable.
If you need multiple outputs write multiple methods in Java class and call them in workflow expression.
You can't.
Workflows expressions are methods bodies.
A statement like
wt.fc.QueryResult activities = wt.fc.PersistenceHelper.manager.find((wt.pds.StatementSpec) activitiesQuery);
ends in a class under $WT_HOME/codebase/wt/workflow/expr/
with a method :
public static Object executemethod_1(Object[] var0, Object[] var1) throws Exception {
wt.fc.QueryResult activities = wt.fc.PersistenceHelper.manager.find((wt.pds.StatementSpec) activitiesQuery);
// some generated code to handle variables...
}
So, you can't use import.
However :
If you have a PDMLink version greater than 10,
You can externalize workflow expression
http://support.ptc.com/cs/help/windchill_hc/wc100_hc/index.jspx?id=WFTemplateExtExpression&action=show
This create a java class under /codebase/ext/wt/workflow/externalize
Then you can do what you want, but you'll have to compile these classes, and do a stop/start in case of modifications.
Basically, it's nothing more than calling external code from the expression, so I don't use it a lot...

How to create a .txt file with the name of the class that called the method?

I am new to programming, so let's see if I can explain this well enough.
I am making a Java package. In one of the classes there is a method that creates a file. The name of that file I have it set up as "file.txt", but I want to change it.
Let's say there is a user working on a new project and he imports the library package (the one I am working on). I want for the file that is created to take the name of the class in which the user is working on. For example if the user calls it in a class named Main, I want the file to be called main.txt or Main.txt.
If this is not clear enough please let me know, I'll try to explain it better.
Thanks
Edit: I've tried the getClass().getSimpleName() but it's not working exactly like I want it to. The method is located inside a library called library and the class is called Main.class but is being used by a use that imported the library library and is working on a class called SuperMario.class I want the text file to be called SuperMario.txt instead with getClass().getSimpleName() applied to my method the file will be called Main.txt, because that is the name of the class the method is in. Unfortunately I can't have the method pass the name as a parameter. Can anyone think of a way around this?
In your library, use stacktrace :
public class Called {
public static void calledMethod() {
System.out.println(Thread.currentThread().getStackTrace()[2].getClassName());
// stackTrace 0 is get stack trace.
// stack trace 1 is calledMethod
// stack trace 2 is the calling method aka main in
}
}
The result will be
eu.plop.test.TestClass
You had to search after stacktrace to see if you want the filename, class name, method's name... and then some string works to remove the package if unused.

GWT.create(clazz) "generics" approach

I have to develop an "generic" wigdet for a GWT/GXT project and to do so I need to create an instance of an object which type is unknown. I found an approach that works perfectly in dev mode but as soon as I try to compile my project and deploy it I get an Only class literals may be used as arguments to GWT.create() error.
Here is a sample of what I do:
public class GenericEditableGrid<M> extends Grid<M>{
private final ToolBar toolBar = new ToolBar();
private final TextButton newItemButton = new TextButton();
protected GridInlineEditing<M> editing;
private final Class<M> clazzM;
public GenericEditableGrid(Class<M> parametrizedClass, String gridTitle, ListStore<M> listStore, ColumnModel<M> cm) {
super(listStore, cm);
clazzM = parametrizedClass;
// ... then I create my widget
bind();
}
private void bind(){
newItemButton.addSelectHandler(new SelectEvent.SelectHandler() {
#Override
public void onSelect(SelectEvent selectEvent) {
editing.cancelEditing();
// it is the folliwing line which is the problem obviously
M element = GWT.create(clazzM);
getStore().add(0, element);
int index = 0;
editing.startEditing(new Grid.GridCell(getStore().indexOf(element), index));
}
});
}
}
And this is how I use it in my subclasses:
super(InternationalString.class, gridTitle, new ListStore<InternationalString>(isprops.key()), buildColumnModel());
Basically, I would like to know what the problem is exactly with this approach and eventually how I should do to make it well.
Please note that my concern is not just to make it work, but more to do it the right way. As I could just avoid the problem using an abstract method which would handle the GWT.create() method in the daughter classes. But this is not the design I want, it just doesn't look right.
What I don't get also is what's the difference between doing this:
MyClass e = GWT.create(MyClass.class);
and:
Class<MyClass> clazz=MyClass.class;
MyClass e = GWT.create(clazz);
Because as far as I am concerned I think this is basically what I am doing and it looks like the same thing. Isn't it?
There's a well-worded explanation in this forum:
As the error message indicates, only class literals may be passed to the GWT.create method. The reason for this is that all GWT.create calls are basically turned into constructors at compile time, using the deferred binding rules for your module. As a result, all classes must be decided at compile time - your code requires that the at runtime the class is decided. This is too late, and so cannot be compiled.
GWT is not proper java, and so cannot be always treated as java. This is one such example of things that cannot be done in gwt. ...
What is it you are trying to do? Either you are making it far more complicated than it needs to be, or you need to write a generator to do it instead of taking this approach.

refractoring java bytecode

I am trying to replace a certain class file with my own in an obfuscated jar. The original class file has methods named "new" and "null" so a quick decompile + compile doesn't work.
I tried compiling and using jbe to add new methods named "new" that relayed everything to "new_symbol" functions (with new_symbol beeing the decompiled version of the original "new" function).
This did not work. ("code segment has wrong length in class file")
Does anyone know of a way to refractor method names in class files? And if that isn't possible, a way to reliably create those "proxy functions"?
From google I learned that there are about 1000+ different backend library's but only jbe as fronted for bytecode editing?
EDIT:
Let me try to illustrate it.
Let's say that there is a jar file with a class that provides a function that logs everything you give it to a database.
I'd like to replace that class file with my own, and it should not only log everything to a database, but also print whatever data it gets to the command line.
The problem is, that class file was obfuscated and the obfuscator gave it public method names like "new" or "null". If you try:
public class replacement{
public void new (string data){
...
}
}
And compile that, you get compilation errors.
My idea was to create this :
public class replacement{
public void newsymbol (string data){
...
}
}
And use a bytecode editor to create a function named "new" that calls "newsymbol" with the same arguments. (but I get "code segment wrong length" and other errors going down this route.
My question therefore could be better frased as "give me a way to intercept calls to a class file who's public methods are named "new" "null" "weird_unicode_symbols""....
Scala allows you to use identifiers in names if you surround them by `.
class f{
def `new`():Int = {
return 3
}
}
jd-gui output
import scala.reflect.ScalaSignature;
#ScalaSignature(bytes=/* snip */)
public class f
{
public int jdMethod_new()
{
return 3;
}
}
I assume that jdMethod_ is prefixed in order to make the identifier valid. There is no jdMethod_ when looking at the class file using a hex editor.
However, this does have a flaw when you need to use public fields; scalac never generates public fields, it always makes them private and creates accessors.
So, what turned out to be the best solution for me was to use a hex editor (as suggested by user60561).
Apparantly, the name of every function and field is only saved once in the class file so if you use names with the same amount of bytes you can hexedit your way to victory.
For me it came down to replacing "new" by "abc" and every strange unicode character with a two-char sequence.
Thanks for all the suggestions.

Bukkit config.yml connection

Alright, I'm trying to program a bukkit plugin and I need to have values from the config file, I've looked up the tutorial at
http://wiki.bukkit.org/Configuration_API_Reference#The_Configuration_Object but this gave me no assistance.
So my code for connect.java is this:
package com.live.AlioGenerica.netherflight;
import java.util.Set;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
public class users {
this.getConfig().options().copyDefaults(true);
public static Boolean getValue(Player p) {
this.getConfig().getBoolean(p);
return true;
}
public static Object setValue(Player p, Boolean v) {
conval.myConfig().set("users." + p + ".boolean", v);
return true;
}
}
config.yml is this:
users:
username: false
userother:true
and etcetera.
How in the world do I connect, I couldn't find anything. I know this is a mess, because I have no idea how to do it.
I myself create Bukkit plugins on my own. The YamlConfiguration is quite easy to use. You can use the method
public void set(String option, Object value)
to set a certain configuration option (option) to a specified value (value) and
public Object get(String option)
and others to get a previously set value. To find all the methods you can use, look them up in Bukkit's JavaDoc for YamlConfiguration.
If you want to save your YamlConfiguration, use
public void save(File f) throws IOException
Besides that, you should work on your coding. Here's a improved version of your code as it is now.
package com.live.AlioGenerica.netherflight;
import java.io.IOException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
public class Users {
private static YamlConfiguration config = null;
// some code
// this method has to be static if you want to use it
// in another static method
public static YamlConfiguration getConfig() {
// load the configuration if it hasn't been loaded yet
if(config == null) {
config = YamlConfiguration.loadConfiguration("path/to/config.yml");
}
// some code
return config;
}
// this will return the boolean you want to get
public static Boolean getValue(Player p) {
return getConfig().getBoolean("users."+p.getName());
}
// use this code to set the value
public static void setValue(Player p, Boolean value) {
getConfig().set("users."+p.getName(), value);
}
// save the configuration
public static void save() {
try{
config.save(new File("path/to/config.yml"));
}catch(IOException e){
e.printStackTrace();
}
}
}
If there are any questions left, just let me know.
#EDIT: Just realized you wanted to save a boolean for a player so that it looks like this in the configuration.
users:
player: true
anotherplayer: false
andsoon: false
Ok, so to deal with the config, the first thing you want to do is actually have a config and put it in the correct place. It looks like you have a config, so you just have to make sure it's located in the resource section of your plugin. After you do that, then you can start dealing with it in your code.
First you want to actually get the config. You do that with this code.
FileConfiguration config = plugin.getConfig();
Simple enough. Now what you want to do is make it so that the plugin will retrieve the values in the config.
config.options().copyDefaults(true);
Finally, you just check to see if the config has been saved in you plugin's data folder.
if (!(new File(plugin.getDataFolder() + config.getName()).exists())) {
plugin.saveDefaultConfig();
}
After you do all those things, you can retrieve the actual values of the config with:
plugin.getConfig().getBoolean("username");
Using this.getConfig() can only be done from the main class that extends JavaPlugin.
You can use the getConfig() and methods built in with that if you do something like this:
public class Example {
MyPlugin plugin;
public String getSomethingFromConfig() {
return plugin.getConfig().getString("path");
}
}
Thats the Easiest way, In My Opinion.
Having a configuration file to get reference variables is very easy to do once you know how to do it. Starting this off you need actually have a config.yml in your src folder of your project. If you are not in Eclipse, I would suggest switching to it to do this easier. Just make a file called config.yml. You can put your variables inside of here that I see you have already did.
After this you need to create the config file when the server starts.
You would need to call a method on your onEnabled method from your main class. You can pull the getConfig() method from other classes also, that I will show you how below.
Since everytime the console enables it will do this method you will need a try/catch operation:
try
{
}
catch (Exception e)
{
e.printStackTrace();
}
The catch is if something goes wrong it will print a stackTrace to console. Inside of the try you will create the config.yml. To do this you will need to make a file variable inside of the try:
File config = new File(getDataFolder(), "config.yml");
Before you can make the config there has to be a data folder for the config to be stored in. To make this data Folder you will need to first see if it is there:
if(!getDataFolder().exists())
{
getDataFolder().mkdirs();
}
After making the data folder you will need to check if the config.yml is already there, and if not create it.
if(!config.exists())
{
getLogger().info("Config.yml not found, Creating");
saveDefaultConfig();
}
Having the saveDefaultConfig(); method will make sure to save your #notes inside of your config file to tell the user what each variable does. This is the best way to save your config file upon creating it. If the config already exists you can put an else and say that it is already there, but this is not necessary.
Make sure all of that is inside of a method that is called in the onEnable() method from your main class. Now that your config is created you can easily get variables from the main class by using the method getConfig()
You can also do this from other classes that I will tell you how to do soon. You can grab any variable from the config by doing getConfig().get ... and past here you can get many things such as strings, integers, booleans, etc... It will then give you a string to find the variable from. This will be the variable name inside of your config.
To use the getConfig() method from other classes you will need to use a constructor. You will need to call an instance from the main class to do this.
In your other class make a constructor like this:
[MainClassName] plugin;
public [OtherClassName]([MainClassName] instance)
{
plugin = instance;
}
The plugin variable will be your instance from the main class. You can use plugin.getConfig() to get the config now.
However, when you register events/commands you will need to match this constructor. Just put this to match the constructor when registering events/commands.
I also notice that you have variables inside of variables. To get the variables inside of the variables you need to get a Configuration Section:
for(String key : instance#getConfig().getConfigurationSection([config path]).getKeys(false))
The String key will be the variable inside of the variable. Since this is iterating, it will get all the variables inside of the variable with the one string key. To get the value of the key variable you would just make a boolean/int/string or whatever is inside and get it by doing:
[String/boolean/int/etc...] value = instance#getConfig().get[Int/String/Boolean/etc...]([first config path]+"."+key)
This is all you need to know about configuration files.

Categories

Resources